summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@qt.io>2017-01-30 11:24:46 +0100
committerMarco Bubke <marco.bubke@qt.io>2017-01-30 13:55:58 +0000
commitc072cdfb8876df773da11222a35b7062dee2ad29 (patch)
tree954c931d5fed150fe4cb14d92a8aeb7285a27794
parentd4b1cb4a65510477d0bc4a888e66c67da6e28237 (diff)
downloadqt-creator-c072cdfb8876df773da11222a35b7062dee2ad29.tar.gz
Clang: Add ClangPchManager
Compiling every header file again and again is quite time comsuming. There are technics to improve this like preambles(a kind of automated precompiled header) but they don't share their data between translation units. This approach provides an automatically generated precompiled header for every project and subproject to improve the loading time. Change-Id: I34f5bd4db21951175920e2a9bbf6b97b1d705969 Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
-rw-r--r--src/libs/clangbackendipc/clangbackendipc-lib.pri22
-rw-r--r--src/libs/clangbackendipc/clangbackendipc_global.h12
-rw-r--r--src/libs/clangbackendipc/pchmanagerclientinterface.cpp49
-rw-r--r--src/libs/clangbackendipc/pchmanagerclientinterface.h43
-rw-r--r--src/libs/clangbackendipc/pchmanagerclientproxy.cpp81
-rw-r--r--src/libs/clangbackendipc/pchmanagerclientproxy.h59
-rw-r--r--src/libs/clangbackendipc/pchmanagerserverinterface.cpp53
-rw-r--r--src/libs/clangbackendipc/pchmanagerserverinterface.h49
-rw-r--r--src/libs/clangbackendipc/pchmanagerserverproxy.cpp74
-rw-r--r--src/libs/clangbackendipc/pchmanagerserverproxy.h66
-rw-r--r--src/libs/clangbackendipc/precompiledheadersupdatedmessage.cpp48
-rw-r--r--src/libs/clangbackendipc/precompiledheadersupdatedmessage.h79
-rw-r--r--src/libs/clangbackendipc/projectpartcontainerv2.cpp55
-rw-r--r--src/libs/clangbackendipc/projectpartcontainerv2.h124
-rw-r--r--src/libs/clangbackendipc/projectpartpch.cpp48
-rw-r--r--src/libs/clangbackendipc/projectpartpch.h88
-rw-r--r--src/libs/clangbackendipc/removepchprojectpartsmessage.cpp42
-rw-r--r--src/libs/clangbackendipc/removepchprojectpartsmessage.h84
-rw-r--r--src/libs/clangbackendipc/updatepchprojectpartsmessage.cpp45
-rw-r--r--src/libs/clangbackendipc/updatepchprojectpartsmessage.h84
-rw-r--r--src/plugins/clangpchmanager/ClangPchManager.json.in21
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager-source.pri22
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager.pro13
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager_dependencies.pri8
-rw-r--r--src/plugins/clangpchmanager/clangpchmanager_global.h42
-rw-r--r--src/plugins/clangpchmanager/clangpchmanagerplugin.cpp100
-rw-r--r--src/plugins/clangpchmanager/clangpchmanagerplugin.h59
-rw-r--r--src/plugins/clangpchmanager/pchmanagerclient.cpp87
-rw-r--r--src/plugins/clangpchmanager/pchmanagerclient.h60
-rw-r--r--src/plugins/clangpchmanager/pchmanagerconnectionclient.cpp75
-rw-r--r--src/plugins/clangpchmanager/pchmanagerconnectionclient.h50
-rw-r--r--src/plugins/clangpchmanager/pchmanagernotifierinterface.cpp43
-rw-r--r--src/plugins/clangpchmanager/pchmanagernotifierinterface.h49
-rw-r--r--src/plugins/clangpchmanager/projectupdater.cpp126
-rw-r--r--src/plugins/clangpchmanager/projectupdater.h70
-rw-r--r--src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp84
-rw-r--r--src/plugins/clangpchmanager/qtcreatorprojectupdater.h51
-rw-r--r--src/plugins/clangrefactoring/clangrefactoring_dependencies.pri4
-rw-r--r--src/plugins/clangrefactoring/refactoringclient.h8
-rw-r--r--src/plugins/cpptools/cppprojectfile.cpp10
-rw-r--r--src/plugins/cpptools/cppprojectfile.h3
-rw-r--r--src/plugins/plugins.pro3
-rw-r--r--src/shared/clang/clang_installation.pri1
-rw-r--r--src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro34
-rw-r--r--src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp108
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpathwatcher.cpp42
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpathwatcher.h392
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpathwatcherinterface.cpp35
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpathwatcherinterface.h47
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpathwatchernotifier.cpp35
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpathwatchernotifier.h40
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri32
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend_global.h52
-rw-r--r--src/tools/clangpchmanagerbackend/source/collectincludesaction.h85
-rw-r--r--src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h114
-rw-r--r--src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h62
-rw-r--r--src/tools/clangpchmanagerbackend/source/environment.h39
-rw-r--r--src/tools/clangpchmanagerbackend/source/idpaths.cpp41
-rw-r--r--src/tools/clangpchmanagerbackend/source/idpaths.h48
-rw-r--r--src/tools/clangpchmanagerbackend/source/includecollector.cpp82
-rw-r--r--src/tools/clangpchmanagerbackend/source/includecollector.h55
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.cpp518
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.h121
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreatorinterface.cpp35
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h45
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp82
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.h61
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchnotcreatederror.h36
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectparts.cpp121
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectparts.h57
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartsinterface.cpp34
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartsinterface.h42
-rw-r--r--src/tools/clangpchmanagerbackend/source/stringcache.h160
-rw-r--r--src/tools/tools.pro3
-rw-r--r--tests/unit/unittest/clang_dependency.pri2
-rw-r--r--tests/unit/unittest/clangpathwatcher-test.cpp313
-rw-r--r--tests/unit/unittest/creator_dependency.pri2
-rw-r--r--tests/unit/unittest/data/includecollector_external1.h3
-rw-r--r--tests/unit/unittest/data/includecollector_external2.h1
-rw-r--r--tests/unit/unittest/data/includecollector_external3.h1
-rw-r--r--tests/unit/unittest/data/includecollector_header1.h2
-rw-r--r--tests/unit/unittest/data/includecollector_header2.h3
-rw-r--r--tests/unit/unittest/data/includecollector_main.cpp4
-rw-r--r--tests/unit/unittest/data/includecollector_main2.cpp4
-rw-r--r--tests/unit/unittest/data/includecollector_main3.cpp4
-rw-r--r--tests/unit/unittest/includecollector-test.cpp98
-rw-r--r--tests/unit/unittest/mockclangpathwatcher.h42
-rw-r--r--tests/unit/unittest/mockclangpathwatchernotifier.h38
-rw-r--r--tests/unit/unittest/mockpchcreator.h48
-rw-r--r--tests/unit/unittest/mockpchmanagerclient.h44
-rw-r--r--tests/unit/unittest/mockpchmanagernotifier.h43
-rw-r--r--tests/unit/unittest/mockpchmanagerserver.h51
-rw-r--r--tests/unit/unittest/mockprojectparts.h46
-rw-r--r--tests/unit/unittest/mockqfilesystemwatcher.h44
-rw-r--r--tests/unit/unittest/mockrefactoringclient.h7
-rw-r--r--tests/unit/unittest/pchcreator-test.cpp298
-rw-r--r--tests/unit/unittest/pchmanagerclient-test.cpp92
-rw-r--r--tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp157
-rw-r--r--tests/unit/unittest/pchmanagerserver-test.cpp184
-rw-r--r--tests/unit/unittest/projectparts-test.cpp189
-rw-r--r--tests/unit/unittest/projectupdater-test.cpp140
-rw-r--r--tests/unit/unittest/smallstring-test.cpp29
-rw-r--r--tests/unit/unittest/stringcache-test.cpp128
-rw-r--r--tests/unit/unittest/testenvironment.h50
-rw-r--r--tests/unit/unittest/unittest.pro26
105 files changed, 6925 insertions, 20 deletions
diff --git a/src/libs/clangbackendipc/clangbackendipc-lib.pri b/src/libs/clangbackendipc/clangbackendipc-lib.pri
index c1fbbd6d84..e6d44d4bcc 100644
--- a/src/libs/clangbackendipc/clangbackendipc-lib.pri
+++ b/src/libs/clangbackendipc/clangbackendipc-lib.pri
@@ -68,7 +68,16 @@ SOURCES += $$PWD/clangcodemodelserverinterface.cpp \
$$PWD/sourcerangesanddiagnosticsforquerymessage.cpp \
$$PWD/sourcerangewithtextcontainer.cpp \
$$PWD/filecontainerv2.cpp \
- $$PWD/cancelmessage.cpp
+ $$PWD/cancelmessage.cpp \
+ $$PWD/pchmanagerclientinterface.cpp \
+ $$PWD/pchmanagerserverinterface.cpp \
+ $$PWD/projectpartcontainerv2.cpp \
+ $$PWD/updatepchprojectpartsmessage.cpp \
+ $$PWD/pchmanagerserverproxy.cpp \
+ $$PWD/pchmanagerclientproxy.cpp \
+ $$PWD/projectpartpch.cpp \
+ $$PWD/precompiledheadersupdatedmessage.cpp \
+ $$PWD/removepchprojectpartsmessage.cpp
HEADERS += \
$$PWD/clangcodemodelserverinterface.h \
@@ -133,6 +142,15 @@ HEADERS += \
$$PWD/sourcerangesanddiagnosticsforquerymessage.h \
$$PWD/sourcerangewithtextcontainer.h \
$$PWD/filecontainerv2.h \
- $$PWD/cancelmessage.h
+ $$PWD/cancelmessage.h \
+ $$PWD/pchmanagerclientinterface.h \
+ $$PWD/pchmanagerserverinterface.h \
+ $$PWD/projectpartcontainerv2.h \
+ $$PWD/updatepchprojectpartsmessage.h \
+ $$PWD/pchmanagerserverproxy.h \
+ $$PWD/pchmanagerclientproxy.h \
+ $$PWD/projectpartpch.h \
+ $$PWD/precompiledheadersupdatedmessage.h \
+ $$PWD/removepchprojectpartsmessage.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
diff --git a/src/libs/clangbackendipc/clangbackendipc_global.h b/src/libs/clangbackendipc/clangbackendipc_global.h
index 306a9d085a..1da9a9f323 100644
--- a/src/libs/clangbackendipc/clangbackendipc_global.h
+++ b/src/libs/clangbackendipc/clangbackendipc_global.h
@@ -45,10 +45,17 @@
# define CLANGBACKENDPROCESSPATH ""
#endif
+#ifdef UNIT_TESTS
+#define unitttest_public public
+#else
+#define unitttest_public private
+#endif
+
namespace Utils {
template <uint Size>
class BasicSmallString;
using SmallString = BasicSmallString<31>;
+using PathString = BasicSmallString<191>;
}
namespace ClangBackEnd {
@@ -124,7 +131,10 @@ enum class MessageType : quint8 {
RequestSourceRangesAndDiagnosticsForQueryMessage,
SourceRangesAndDiagnosticsForQueryMessage,
- CancelMessage
+ CancelMessage,
+ UpdatePchProjectPartsMessage,
+ RemovePchProjectPartsMessage,
+ PrecompiledHeadersUpdatedMessage
};
template<MessageType messageEnumeration>
diff --git a/src/libs/clangbackendipc/pchmanagerclientinterface.cpp b/src/libs/clangbackendipc/pchmanagerclientinterface.cpp
new file mode 100644
index 0000000000..b7e40f3f5d
--- /dev/null
+++ b/src/libs/clangbackendipc/pchmanagerclientinterface.cpp
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "pchmanagerclientinterface.h"
+#include "messageenvelop.h"
+
+#include <precompiledheadersupdatedmessage.h>
+
+#include <QDebug>
+
+namespace ClangBackEnd {
+
+void PchManagerClientInterface::dispatch(const MessageEnvelop &messageEnvelop)
+{
+ switch (messageEnvelop.messageType()) {
+ case MessageType::AliveMessage:
+ alive();
+ break;
+ case MessageType::PrecompiledHeadersUpdatedMessage:
+ precompiledHeadersUpdated(messageEnvelop.message<PrecompiledHeadersUpdatedMessage>());
+ break;
+ default:
+ qWarning() << "Unknown IpcClientMessage";
+ }
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/pchmanagerclientinterface.h b/src/libs/clangbackendipc/pchmanagerclientinterface.h
new file mode 100644
index 0000000000..771951641a
--- /dev/null
+++ b/src/libs/clangbackendipc/pchmanagerclientinterface.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** 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
+
+#include "ipcclientinterface.h"
+
+namespace ClangBackEnd {
+
+class PrecompiledHeadersUpdatedMessage;
+
+class CMBIPC_EXPORT PchManagerClientInterface : public IpcClientInterface
+{
+public:
+ void dispatch(const MessageEnvelop &messageEnvelop) override;
+
+ virtual void alive() = 0;
+ virtual void precompiledHeadersUpdated(PrecompiledHeadersUpdatedMessage &&message) = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/pchmanagerclientproxy.cpp b/src/libs/clangbackendipc/pchmanagerclientproxy.cpp
new file mode 100644
index 0000000000..ad583113bb
--- /dev/null
+++ b/src/libs/clangbackendipc/pchmanagerclientproxy.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "pchmanagerclientproxy.h"
+
+#include "cmbalivemessage.h"
+#include "messageenvelop.h"
+#include "pchmanagerserverinterface.h"
+#include "precompiledheadersupdatedmessage.h"
+
+#include <QDebug>
+#include <QIODevice>
+
+namespace ClangBackEnd {
+
+PchManagerClientProxy::PchManagerClientProxy(PchManagerServerInterface *server, QIODevice *ioDevice)
+ : writeMessageBlock(ioDevice),
+ readMessageBlock(ioDevice),
+ server(server),
+ ioDevice(ioDevice)
+{
+ QObject::connect(ioDevice, &QIODevice::readyRead, [this] () {PchManagerClientProxy::readMessages();});
+}
+
+PchManagerClientProxy::PchManagerClientProxy(PchManagerClientProxy &&other)
+ : writeMessageBlock(std::move(other.writeMessageBlock)),
+ readMessageBlock(std::move(other.readMessageBlock)),
+ server(std::move(other.server)),
+ ioDevice(std::move(other.ioDevice))
+{
+}
+
+PchManagerClientProxy &PchManagerClientProxy::operator=(PchManagerClientProxy &&other)
+{
+ writeMessageBlock = std::move(other.writeMessageBlock);
+ readMessageBlock = std::move(other.readMessageBlock);
+ server = std::move(other.server);
+ ioDevice = std::move(other.ioDevice);
+
+ return *this;
+}
+
+void PchManagerClientProxy::readMessages()
+{
+ for (const MessageEnvelop &message : readMessageBlock.readAll())
+ server->dispatch(message);
+}
+
+void PchManagerClientProxy::alive()
+{
+ writeMessageBlock.write(AliveMessage());
+}
+
+void PchManagerClientProxy::precompiledHeadersUpdated(PrecompiledHeadersUpdatedMessage &&message)
+{
+ writeMessageBlock.write(message);
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/pchmanagerclientproxy.h b/src/libs/clangbackendipc/pchmanagerclientproxy.h
new file mode 100644
index 0000000000..210e5b0125
--- /dev/null
+++ b/src/libs/clangbackendipc/pchmanagerclientproxy.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** 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
+
+#include "clangbackendipc_global.h"
+#include "pchmanagerclientinterface.h"
+#include "readmessageblock.h"
+#include "writemessageblock.h"
+
+namespace ClangBackEnd {
+
+class PchManagerServerInterface;
+
+class CMBIPC_EXPORT PchManagerClientProxy : public PchManagerClientInterface
+{
+public:
+ explicit PchManagerClientProxy(PchManagerServerInterface *server, QIODevice *ioDevice);
+ PchManagerClientProxy(const PchManagerClientProxy&) = delete;
+ const PchManagerClientProxy &operator=(const PchManagerClientProxy&) = delete;
+
+ PchManagerClientProxy(PchManagerClientProxy&&other);
+ PchManagerClientProxy &operator=(PchManagerClientProxy&&other);
+
+ void readMessages();
+
+ void alive() override;
+ void precompiledHeadersUpdated(PrecompiledHeadersUpdatedMessage &&message) override;
+
+private:
+ ClangBackEnd::WriteMessageBlock writeMessageBlock;
+ ClangBackEnd::ReadMessageBlock readMessageBlock;
+ PchManagerServerInterface *server = nullptr;
+ QIODevice *ioDevice = nullptr;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/pchmanagerserverinterface.cpp b/src/libs/clangbackendipc/pchmanagerserverinterface.cpp
new file mode 100644
index 0000000000..1a6d9d4a25
--- /dev/null
+++ b/src/libs/clangbackendipc/pchmanagerserverinterface.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "pchmanagerserverinterface.h"
+
+#include "messageenvelop.h"
+#include "removepchprojectpartsmessage.h"
+#include "updatepchprojectpartsmessage.h"
+
+#include <QDebug>
+
+namespace ClangBackEnd {
+
+void PchManagerServerInterface::dispatch(const MessageEnvelop &messageEnvelop)
+{
+ switch (messageEnvelop.messageType()) {
+ case MessageType::EndMessage:
+ end();
+ break;
+ case MessageType::UpdatePchProjectPartsMessage:
+ updatePchProjectParts(messageEnvelop.message<UpdatePchProjectPartsMessage>());
+ break;
+ case MessageType::RemovePchProjectPartsMessage:
+ removePchProjectParts(messageEnvelop.message<RemovePchProjectPartsMessage>());
+ break;
+ default:
+ qWarning() << "Unknown IpcClientMessage";
+ }
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/pchmanagerserverinterface.h b/src/libs/clangbackendipc/pchmanagerserverinterface.h
new file mode 100644
index 0000000000..a4a8ed683d
--- /dev/null
+++ b/src/libs/clangbackendipc/pchmanagerserverinterface.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** 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
+
+#include "ipcserverinterface.h"
+
+#include <memory>
+
+namespace ClangBackEnd {
+
+class PchManagerClientInterface;
+class RemovePchProjectPartsMessage;
+class UpdatePchProjectPartsMessage;
+
+
+class CMBIPC_EXPORT PchManagerServerInterface : public IpcServerInterface<PchManagerClientInterface>
+{
+public:
+ void dispatch(const MessageEnvelop &messageEnvelop) override;
+
+ virtual void end() = 0;
+ virtual void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) = 0;
+ virtual void removePchProjectParts(RemovePchProjectPartsMessage &&message) = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/pchmanagerserverproxy.cpp b/src/libs/clangbackendipc/pchmanagerserverproxy.cpp
new file mode 100644
index 0000000000..d513fddc87
--- /dev/null
+++ b/src/libs/clangbackendipc/pchmanagerserverproxy.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "pchmanagerserverproxy.h"
+
+#include "cmbendmessage.h"
+#include "messageenvelop.h"
+#include "pchmanagerclientinterface.h"
+#include "removepchprojectpartsmessage.h"
+#include "updatepchprojectpartsmessage.h"
+
+#include <QIODevice>
+#include <QVector>
+
+namespace ClangBackEnd {
+
+PchManagerServerProxy::PchManagerServerProxy(PchManagerClientInterface *client, QIODevice *ioDevice)
+ : writeMessageBlock(ioDevice),
+ readMessageBlock(ioDevice),
+ client(client)
+{
+ QObject::connect(ioDevice, &QIODevice::readyRead, [this] () { readMessages(); });
+}
+
+void PchManagerServerProxy::end()
+{
+ writeMessageBlock.write(EndMessage());
+}
+
+void PchManagerServerProxy::updatePchProjectParts(UpdatePchProjectPartsMessage &&message)
+{
+ writeMessageBlock.write(message);
+}
+
+void PchManagerServerProxy::removePchProjectParts(RemovePchProjectPartsMessage &&message)
+{
+ writeMessageBlock.write(message);
+}
+
+void PchManagerServerProxy::readMessages()
+{
+ for (const auto &message : readMessageBlock.readAll())
+ client->dispatch(message);
+}
+
+void PchManagerServerProxy::resetCounter()
+{
+ writeMessageBlock.resetCounter();
+ readMessageBlock.resetCounter();
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/pchmanagerserverproxy.h b/src/libs/clangbackendipc/pchmanagerserverproxy.h
new file mode 100644
index 0000000000..0b4e593bc1
--- /dev/null
+++ b/src/libs/clangbackendipc/pchmanagerserverproxy.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** 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
+
+#include "clangbackendipc_global.h"
+#include "pchmanagerserverinterface.h"
+#include "readmessageblock.h"
+#include "writemessageblock.h"
+
+#include <QtGlobal>
+
+#include <memory>
+
+QT_BEGIN_NAMESPACE
+class QIODevice;
+QT_END_NAMESPACE
+
+namespace ClangBackEnd {
+
+class PchManagerClientInterface;
+
+class CMBIPC_EXPORT PchManagerServerProxy final : public PchManagerServerInterface
+{
+public:
+ explicit PchManagerServerProxy(PchManagerClientInterface *client, QIODevice *ioDevice);
+ PchManagerServerProxy(const PchManagerServerProxy&) = delete;
+ const PchManagerServerProxy &operator=(const PchManagerServerProxy&) = delete;
+
+ void end() override;
+ void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) override;
+ void removePchProjectParts(RemovePchProjectPartsMessage &&message) override;
+
+ void readMessages();
+
+ void resetCounter();
+
+private:
+ ClangBackEnd::WriteMessageBlock writeMessageBlock;
+ ClangBackEnd::ReadMessageBlock readMessageBlock;
+ PchManagerClientInterface *client = nullptr;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/precompiledheadersupdatedmessage.cpp b/src/libs/clangbackendipc/precompiledheadersupdatedmessage.cpp
new file mode 100644
index 0000000000..38c56be38b
--- /dev/null
+++ b/src/libs/clangbackendipc/precompiledheadersupdatedmessage.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "precompiledheadersupdatedmessage.h"
+
+#include <QDebug>
+
+namespace ClangBackEnd {
+
+CMBIPC_EXPORT QDebug operator<<(QDebug debug, const PrecompiledHeadersUpdatedMessage &)
+{
+ debug.nospace() << "PrecompiledHeaderUpdatedMessage()";
+
+ return debug;
+}
+
+std::ostream &operator<<(std::ostream &out, const PrecompiledHeadersUpdatedMessage &message)
+{
+ out << "("
+ << message.projectPartPchs()
+ << ")";
+
+ return out;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/precompiledheadersupdatedmessage.h b/src/libs/clangbackendipc/precompiledheadersupdatedmessage.h
new file mode 100644
index 0000000000..7780957e79
--- /dev/null
+++ b/src/libs/clangbackendipc/precompiledheadersupdatedmessage.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** 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
+
+#include "projectpartpch.h"
+
+namespace ClangBackEnd {
+
+class PrecompiledHeadersUpdatedMessage
+{
+public:
+ PrecompiledHeadersUpdatedMessage() = default;
+ PrecompiledHeadersUpdatedMessage(std::vector<ProjectPartPch> &&projectPartPchs)
+ : projectPartPchs_(std::move(projectPartPchs))
+ {}
+
+ const std::vector<ProjectPartPch> &projectPartPchs() const
+ {
+ return projectPartPchs_;
+ }
+
+ friend QDataStream &operator<<(QDataStream &out, const PrecompiledHeadersUpdatedMessage &message)
+ {
+ out << message.projectPartPchs_;
+
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, PrecompiledHeadersUpdatedMessage &message)
+ {
+ in >> message.projectPartPchs_;
+
+ return in;
+ }
+
+ friend bool operator==(const PrecompiledHeadersUpdatedMessage &first,
+ const PrecompiledHeadersUpdatedMessage &second)
+ {
+ return first.projectPartPchs_ == second.projectPartPchs_;
+ }
+
+ PrecompiledHeadersUpdatedMessage clone() const
+ {
+ return PrecompiledHeadersUpdatedMessage(Utils::clone(projectPartPchs_));
+ }
+
+private:
+ std::vector<ProjectPartPch> projectPartPchs_;
+};
+
+CMBIPC_EXPORT QDebug operator<<(QDebug debug, const PrecompiledHeadersUpdatedMessage &message);
+std::ostream &operator<<(std::ostream &out, const PrecompiledHeadersUpdatedMessage &message);
+
+DECLARE_MESSAGE(PrecompiledHeadersUpdatedMessage)
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/projectpartcontainerv2.cpp b/src/libs/clangbackendipc/projectpartcontainerv2.cpp
new file mode 100644
index 0000000000..89b489ee5b
--- /dev/null
+++ b/src/libs/clangbackendipc/projectpartcontainerv2.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "projectpartcontainerv2.h"
+
+namespace ClangBackEnd {
+namespace V2 {
+
+QDebug operator<<(QDebug debug, const ProjectPartContainer &container)
+{
+ debug.nospace() << "ProjectPartContainer("
+ << container.projectPartId() << ","
+ << container.arguments() << ", "
+ << container.headerPaths() << ", "
+ << container.sourcePaths()
+ << ")";
+
+ return debug;
+}
+
+std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container)
+{
+ out << "("
+ << container.projectPartId() << ", "
+ << container.arguments() << ", "
+ << container.headerPaths() << ", "
+ << container.sourcePaths()<< ")";
+
+ return out;
+}
+
+} // namespace V2
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/projectpartcontainerv2.h b/src/libs/clangbackendipc/projectpartcontainerv2.h
new file mode 100644
index 0000000000..db5781daac
--- /dev/null
+++ b/src/libs/clangbackendipc/projectpartcontainerv2.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** 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
+
+#include "clangbackendipc_global.h"
+
+#include <utils/smallstringio.h>
+
+namespace ClangBackEnd {
+namespace V2 {
+
+class ProjectPartContainer
+{
+public:
+ ProjectPartContainer() = default;
+ ProjectPartContainer(Utils::SmallString &&projectPartId,
+ Utils::SmallStringVector &&arguments,
+ Utils::SmallStringVector &&headerPaths,
+ Utils::SmallStringVector &&sourcePaths)
+ : projectPartId_(std::move(projectPartId)),
+ arguments_(std::move(arguments)),
+ headerPaths_(std::move(headerPaths)),
+ sourcePaths_(std::move(sourcePaths))
+ {
+ }
+
+ const Utils::SmallString &projectPartId() const
+ {
+ return projectPartId_;
+ }
+
+ const Utils::SmallStringVector &arguments() const
+ {
+ return arguments_;
+ }
+
+ const Utils::SmallStringVector &sourcePaths() const
+ {
+ return sourcePaths_;
+ }
+
+ const Utils::SmallStringVector &headerPaths() const
+ {
+ return headerPaths_;
+ }
+
+ friend QDataStream &operator<<(QDataStream &out, const ProjectPartContainer &container)
+ {
+ out << container.projectPartId_;
+ out << container.arguments_;
+ out << container.headerPaths_;
+ out << container.sourcePaths_;
+
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, ProjectPartContainer &container)
+ {
+ in >> container.projectPartId_;
+ in >> container.arguments_;
+ in >> container.headerPaths_;
+ in >> container.sourcePaths_;
+
+ return in;
+ }
+
+ friend bool operator==(const ProjectPartContainer &first, const ProjectPartContainer &second)
+ {
+ return first.projectPartId_ == second.projectPartId_
+ && first.arguments_ == second.arguments_
+ && first.headerPaths_ == second.headerPaths_
+ && first.sourcePaths_ == second.sourcePaths_;
+ }
+
+ friend bool operator<(const ProjectPartContainer &first, const ProjectPartContainer &second)
+ {
+ return std::tie(first.projectPartId_, first.arguments_, first.headerPaths_, first.sourcePaths_)
+ < std::tie(second.projectPartId_, second.arguments_, second.headerPaths_, second.sourcePaths_);
+ }
+
+ ProjectPartContainer clone() const
+ {
+ return ProjectPartContainer(projectPartId_.clone(),
+ arguments_.clone(),
+ headerPaths_.clone(),
+ sourcePaths_.clone());
+ }
+
+private:
+ Utils::SmallString projectPartId_;
+ Utils::SmallStringVector arguments_;
+ Utils::SmallStringVector headerPaths_;
+ Utils::SmallStringVector sourcePaths_;
+};
+
+using ProjectPartContainers = std::vector<ProjectPartContainer>;
+
+QDebug operator<<(QDebug debug, const ProjectPartContainer &container);
+std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container);
+} // namespace V2
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/projectpartpch.cpp b/src/libs/clangbackendipc/projectpartpch.cpp
new file mode 100644
index 0000000000..0df291b3df
--- /dev/null
+++ b/src/libs/clangbackendipc/projectpartpch.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "projectpartpch.h"
+
+namespace ClangBackEnd {
+
+QDebug operator<<(QDebug debug, const ProjectPartPch &projectPartPch)
+{
+ debug.nospace() << "FileContainer("
+ << projectPartPch.id() << ", "
+ << projectPartPch.path() << ")";
+
+ return debug;
+}
+
+std::ostream &operator<<(std::ostream &out, const ProjectPartPch &projectPartPch)
+{
+ out << "("
+ << projectPartPch.id() << ", "
+ << projectPartPch.path() << ")";
+
+ return out;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/projectpartpch.h b/src/libs/clangbackendipc/projectpartpch.h
new file mode 100644
index 0000000000..0d541671c2
--- /dev/null
+++ b/src/libs/clangbackendipc/projectpartpch.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** 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
+
+#include "clangbackendipc_global.h"
+
+#include <utils/smallstringio.h>
+
+namespace ClangBackEnd {
+
+class ProjectPartPch
+{
+public:
+ ProjectPartPch() = default;
+ ProjectPartPch(Utils::SmallString &&projectPartId, Utils::SmallString &&pchPath)
+ : projectPartId(std::move(projectPartId)),
+ pchPath(std::move(pchPath))
+ {}
+
+ const Utils::SmallString &id() const
+ {
+ return projectPartId;
+ }
+
+ const Utils::SmallString &path() const
+ {
+ return pchPath;
+ }
+
+ friend QDataStream &operator<<(QDataStream &out, const ProjectPartPch &container)
+ {
+ out << container.projectPartId;
+ out << container.pchPath;
+
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, ProjectPartPch &container)
+ {
+ in >> container.projectPartId;
+ in >> container.pchPath;
+
+ return in;
+ }
+
+ friend bool operator==(const ProjectPartPch &first,
+ const ProjectPartPch &second)
+ {
+ return first.projectPartId == second.projectPartId
+ && first.pchPath == second.pchPath;
+ }
+
+ ProjectPartPch clone() const
+ {
+ return ProjectPartPch(projectPartId.clone(), pchPath.clone());
+ }
+
+private:
+ Utils::SmallString projectPartId;
+ Utils::SmallString pchPath;
+};
+
+CMBIPC_EXPORT QDebug operator<<(QDebug debug, const ProjectPartPch &projectPartPch);
+std::ostream &operator<<(std::ostream &out, const ProjectPartPch &projectPartPch);
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/removepchprojectpartsmessage.cpp b/src/libs/clangbackendipc/removepchprojectpartsmessage.cpp
new file mode 100644
index 0000000000..24c657336a
--- /dev/null
+++ b/src/libs/clangbackendipc/removepchprojectpartsmessage.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "removepchprojectpartsmessage.h"
+
+namespace ClangBackEnd {
+
+CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RemovePchProjectPartsMessage &message)
+{
+ debug.nospace() << "RemoveProjectPartsMessage("
+ << message.projectsPartIds() << ")";
+
+ return debug;
+}
+
+std::ostream &operator<<(std::ostream &out, const RemovePchProjectPartsMessage &message)
+{
+ return out << "(" << message.projectsPartIds() << ")";
+}
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/removepchprojectpartsmessage.h b/src/libs/clangbackendipc/removepchprojectpartsmessage.h
new file mode 100644
index 0000000000..2c052bab22
--- /dev/null
+++ b/src/libs/clangbackendipc/removepchprojectpartsmessage.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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
+
+#include "projectpartcontainerv2.h"
+
+namespace ClangBackEnd {
+
+class RemovePchProjectPartsMessage
+{
+public:
+ RemovePchProjectPartsMessage() = default;
+ RemovePchProjectPartsMessage(Utils::SmallStringVector &&projectsPartIds)
+ : projectsPartIds_(std::move(projectsPartIds))
+ {}
+
+ const Utils::SmallStringVector &projectsPartIds() const
+ {
+ return projectsPartIds_;
+ }
+
+ Utils::SmallStringVector takeProjectsPartIds()
+ {
+ return std::move(projectsPartIds_);
+ }
+
+ friend QDataStream &operator<<(QDataStream &out, const RemovePchProjectPartsMessage &message)
+ {
+ out << message.projectsPartIds_;
+
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, RemovePchProjectPartsMessage &message)
+ {
+ in >> message.projectsPartIds_;
+
+ return in;
+ }
+
+ friend bool operator==(const RemovePchProjectPartsMessage &first,
+ const RemovePchProjectPartsMessage &second)
+ {
+ return first.projectsPartIds_ == second.projectsPartIds_;
+ }
+
+ RemovePchProjectPartsMessage clone() const
+ {
+ return RemovePchProjectPartsMessage(projectsPartIds_.clone());
+ }
+
+private:
+ Utils::SmallStringVector projectsPartIds_;
+};
+
+CMBIPC_EXPORT QDebug operator<<(QDebug debug, const RemovePchProjectPartsMessage &message);
+std::ostream &operator<<(std::ostream &out, const RemovePchProjectPartsMessage &message);
+
+DECLARE_MESSAGE(RemovePchProjectPartsMessage)
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/updatepchprojectpartsmessage.cpp b/src/libs/clangbackendipc/updatepchprojectpartsmessage.cpp
new file mode 100644
index 0000000000..f86ef12aac
--- /dev/null
+++ b/src/libs/clangbackendipc/updatepchprojectpartsmessage.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "updatepchprojectpartsmessage.h"
+
+namespace ClangBackEnd {
+
+QDebug operator<<(QDebug debug, const UpdatePchProjectPartsMessage &message)
+{
+ debug.nospace() << "UpdatePchProjectPartsMessage("
+ << message.projectsParts() << ")";
+
+ return debug;
+}
+
+std::ostream &operator<<(std::ostream &out, const UpdatePchProjectPartsMessage &message)
+{
+ return out << "("
+ << message.projectsParts()
+ << ")";
+}
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangbackendipc/updatepchprojectpartsmessage.h b/src/libs/clangbackendipc/updatepchprojectpartsmessage.h
new file mode 100644
index 0000000000..dc5534c0b3
--- /dev/null
+++ b/src/libs/clangbackendipc/updatepchprojectpartsmessage.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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
+
+#include "projectpartcontainerv2.h"
+
+namespace ClangBackEnd {
+
+class UpdatePchProjectPartsMessage
+{
+public:
+ UpdatePchProjectPartsMessage() = default;
+ UpdatePchProjectPartsMessage(V2::ProjectPartContainers &&projectsParts)
+ : projectsParts_(std::move(projectsParts))
+ {}
+
+ const V2::ProjectPartContainers &projectsParts() const
+ {
+ return projectsParts_;
+ }
+
+ V2::ProjectPartContainers takeProjectsParts()
+ {
+ return std::move(projectsParts_);
+ }
+
+ friend QDataStream &operator<<(QDataStream &out, const UpdatePchProjectPartsMessage &message)
+ {
+ out << message.projectsParts_;
+
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, UpdatePchProjectPartsMessage &message)
+ {
+ in >> message.projectsParts_;
+
+ return in;
+ }
+
+ friend bool operator==(const UpdatePchProjectPartsMessage &first,
+ const UpdatePchProjectPartsMessage &second)
+ {
+ return first.projectsParts_ == second.projectsParts_;
+ }
+
+ UpdatePchProjectPartsMessage clone() const
+ {
+ return UpdatePchProjectPartsMessage(Utils::clone(projectsParts_));
+ }
+
+private:
+ V2::ProjectPartContainers projectsParts_;
+};
+
+CMBIPC_EXPORT QDebug operator<<(QDebug debug, const UpdatePchProjectPartsMessage &message);
+std::ostream &operator<<(std::ostream &out, const UpdatePchProjectPartsMessage &message);
+
+DECLARE_MESSAGE(UpdatePchProjectPartsMessage)
+
+} // namespace ClangBackEnd
diff --git a/src/plugins/clangpchmanager/ClangPchManager.json.in b/src/plugins/clangpchmanager/ClangPchManager.json.in
new file mode 100644
index 0000000000..5a4bcb953d
--- /dev/null
+++ b/src/plugins/clangpchmanager/ClangPchManager.json.in
@@ -0,0 +1,21 @@
+{
+ \"Name\" : \"ClangPchManager\",
+ \"Version\" : \"$$QTCREATOR_VERSION\",
+ \"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
+ \"Experimental\" : true,
+ \"HiddenByDefault\": true,
+ \"Vendor\" : \"The Qt Company Ltd\",
+ \"Copyright\" : \"(C) 2016 The Qt Company Ltd\",
+ \"License\" : [ \"Commercial Usage\",
+ \"\",
+ \"Licensees holding valid Qt Commercial licenses may use this plugin in accordance with the Qt Commercial License Agreement provided with the Software or, alternatively, in accordance with the terms contained in a written agreement between you and The Qt Company.\",
+ \"\",
+ \"GNU General Public License Usage\",
+ \"\",
+ \"Alternatively, this plugin 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 plugin. 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.\"
+ ],
+ \"Category\" : \"C++\",
+ \"Description\" : \"Clang precompiled header plugin.\",
+ \"Url\" : \"http://www.qt.io\",
+ $$dependencyList
+}
diff --git a/src/plugins/clangpchmanager/clangpchmanager-source.pri b/src/plugins/clangpchmanager/clangpchmanager-source.pri
new file mode 100644
index 0000000000..fd5b61a24d
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangpchmanager-source.pri
@@ -0,0 +1,22 @@
+shared|dll {
+ DEFINES += CLANGPCHMANAGER_LIB
+} else {
+ DEFINES += CLANGPCHMANAGER_STATIC_LIB
+}
+
+INCLUDEPATH += $$PWD
+
+HEADERS += \
+ $$PWD/pchmanagerclient.h \
+ $$PWD/pchmanagernotifierinterface.h \
+ $$PWD/pchmanagerconnectionclient.h \
+ $$PWD/clangpchmanager_global.h \
+ $$PWD/projectupdater.h
+
+
+SOURCES += \
+ $$PWD/pchmanagerclient.cpp \
+ $$PWD/pchmanagernotifierinterface.cpp \
+ $$PWD/pchmanagerconnectionclient.cpp \
+ $$PWD/projectupdater.cpp
+
diff --git a/src/plugins/clangpchmanager/clangpchmanager.pro b/src/plugins/clangpchmanager/clangpchmanager.pro
new file mode 100644
index 0000000000..10c8f1b70b
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangpchmanager.pro
@@ -0,0 +1,13 @@
+include(../../qtcreatorplugin.pri)
+include(clangpchmanager-source.pri)
+include(../../shared/clang/clang_installation.pri)
+
+DEFINES += CLANG_VERSION=\\\"$${LLVM_VERSION}\\\"
+DEFINES += "\"CLANG_RESOURCE_DIR=\\\"$${LLVM_LIBDIR}/clang/$${LLVM_VERSION}/include\\\"\""
+
+HEADERS += \
+ $$PWD/clangpchmanagerplugin.h \
+ qtcreatorprojectupdater.h
+SOURCES += \
+ $$PWD/clangpchmanagerplugin.cpp \
+ qtcreatorprojectupdater.cpp
diff --git a/src/plugins/clangpchmanager/clangpchmanager_dependencies.pri b/src/plugins/clangpchmanager/clangpchmanager_dependencies.pri
new file mode 100644
index 0000000000..281eca80d5
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangpchmanager_dependencies.pri
@@ -0,0 +1,8 @@
+QTC_PLUGIN_NAME = ClangPchManager
+QTC_LIB_DEPENDS += \
+ utils \
+ clangbackendipc
+QTC_PLUGIN_DEPENDS += \
+ coreplugin \
+ cpptools
+
diff --git a/src/plugins/clangpchmanager/clangpchmanager_global.h b/src/plugins/clangpchmanager/clangpchmanager_global.h
new file mode 100644
index 0000000000..3a75e8e5b6
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangpchmanager_global.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** 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
+
+#include <qglobal.h>
+
+#if defined(CLANGPCHMANAGER_LIB)
+# define CLANGPCHMANAGER_EXPORT Q_DECL_EXPORT
+#elif defined(CLANGPCHMANAGER_STATIC_LIB) // Abuse single files for manual tests
+# define CLANGPCHMANAGER_EXPORT
+#else
+# define CLANGPCHMANAGER_EXPORT Q_DECL_IMPORT
+#endif
+
+#ifdef UNIT_TESTS
+#define unittest_public public
+#else
+#define unittest_public private
+#endif
diff --git a/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
new file mode 100644
index 0000000000..4c53696807
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangpchmanagerplugin.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "clangpchmanagerplugin.h"
+
+#include "pchmanagerconnectionclient.h"
+#include "pchmanagerclient.h"
+#include "qtcreatorprojectupdater.h"
+
+#include <coreplugin/icore.h>
+#include <extensionsystem/pluginmanager.h>
+
+#include <utils/hostosinfo.h>
+
+namespace ClangPchManager {
+
+namespace {
+
+QString backendProcessPath()
+{
+ return Core::ICore::libexecPath()
+ + QStringLiteral("/clangpchmanagerbackend")
+ + QStringLiteral(QTC_HOST_EXE_SUFFIX);
+}
+
+} // anonymous namespace
+
+class ClangPchManagerPluginData
+{
+public:
+ PchManagerClient pchManagerClient;
+ PchManagerConnectionClient connectionClient{&pchManagerClient};
+ QtCreatorProjectUpdater projectUpdate{connectionClient.serverProxy(), pchManagerClient};
+};
+
+std::unique_ptr<ClangPchManagerPluginData> ClangPchManagerPlugin::d;
+
+ClangPchManagerPlugin::ClangPchManagerPlugin() = default;
+ClangPchManagerPlugin::~ClangPchManagerPlugin() = default;
+
+bool ClangPchManagerPlugin::initialize(const QStringList & /*arguments*/, QString * /*errorMessage*/)
+{
+ d.reset(new ClangPchManagerPluginData);
+
+ startBackend();
+
+ return true;
+}
+
+void ClangPchManagerPlugin::extensionsInitialized()
+{
+}
+
+ExtensionSystem::IPlugin::ShutdownFlag ClangPchManagerPlugin::aboutToShutdown()
+{
+ d->connectionClient.finishProcess();
+
+ d.reset();
+
+ return SynchronousShutdown;
+}
+
+void ClangPchManagerPlugin::startBackend()
+{
+ d->pchManagerClient.setConnectionClient(&d->connectionClient);
+
+ d->connectionClient.setProcessPath(backendProcessPath());
+
+ d->connectionClient.startProcessAndConnectToServerAsynchronously();
+}
+
+
+PchManagerClient &ClangPchManagerPlugin::pchManagerClient()
+{
+ return d->pchManagerClient;
+}
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangpchmanager/clangpchmanagerplugin.h b/src/plugins/clangpchmanager/clangpchmanagerplugin.h
new file mode 100644
index 0000000000..666e3df5c9
--- /dev/null
+++ b/src/plugins/clangpchmanager/clangpchmanagerplugin.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** 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
+
+#include <extensionsystem/iplugin.h>
+
+#include <memory>
+
+namespace ClangPchManager {
+
+class ClangPchManagerPluginData;
+class PchManagerClient;
+
+class ClangPchManagerPlugin : public ExtensionSystem::IPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "ClangPchManager.json")
+
+public:
+ ClangPchManagerPlugin();
+ ~ClangPchManagerPlugin();
+
+ bool initialize(const QStringList &arguments, QString *errorMessage);
+ void extensionsInitialized();
+ ShutdownFlag aboutToShutdown();
+
+ static PchManagerClient &pchManagerClient();
+
+private:
+ void startBackend();
+
+private:
+ static std::unique_ptr<ClangPchManagerPluginData> d;
+};
+
+} // namespace ClangRefactoring
diff --git a/src/plugins/clangpchmanager/pchmanagerclient.cpp b/src/plugins/clangpchmanager/pchmanagerclient.cpp
new file mode 100644
index 0000000000..d901946fb6
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagerclient.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "pchmanagerclient.h"
+
+#include <precompiledheadersupdatedmessage.h>
+#include <pchmanagerconnectionclient.h>
+
+#include <pchmanagernotifierinterface.h>
+
+#include <algorithm>
+
+namespace ClangPchManager {
+
+void PchManagerClient::alive()
+{
+ if (m_connectionClient)
+ m_connectionClient->resetProcessAliveTimer();
+}
+
+void PchManagerClient::precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message)
+{
+ for (const ClangBackEnd::ProjectPartPch &projectPartPch : message.projectPartPchs())
+ precompiledHeaderUpdated(projectPartPch.id(), projectPartPch.path());
+}
+
+void PchManagerClient::precompiledHeaderRemoved(const QString &projectPartId)
+{
+ for (auto notifier : m_notifiers)
+ notifier->precompiledHeaderRemoved(projectPartId);
+}
+
+void PchManagerClient::setConnectionClient(PchManagerConnectionClient *connectionClient)
+{
+ m_connectionClient = connectionClient;
+}
+
+void PchManagerClient::attach(PchManagerNotifierInterface *notifier)
+{
+ m_notifiers.push_back(notifier);
+}
+
+void PchManagerClient::detach(PchManagerNotifierInterface *notifierToBeDeleted)
+{
+ auto newEnd = std::partition(m_notifiers.begin(),
+ m_notifiers.end(),
+ [&] (PchManagerNotifierInterface *notifier) {
+ return notifier != notifierToBeDeleted;
+ });
+
+ m_notifiers.erase(newEnd, m_notifiers.end());
+}
+
+const std::vector<PchManagerNotifierInterface *> &PchManagerClient::notifiers() const
+{
+ return m_notifiers;
+}
+
+void PchManagerClient::precompiledHeaderUpdated(const QString &projectPartId, const QString &pchFilePath)
+{
+ for (auto notifier : m_notifiers)
+ notifier->precompiledHeaderUpdated(projectPartId, pchFilePath);
+}
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/pchmanagerclient.h b/src/plugins/clangpchmanager/pchmanagerclient.h
new file mode 100644
index 0000000000..173b107865
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagerclient.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** 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
+
+#include <pchmanagerclientinterface.h>
+
+#include <vector>
+
+namespace ClangPchManager {
+class PchManagerConnectionClient;
+
+class PchManagerNotifierInterface;
+
+class PchManagerClient final : public ClangBackEnd::PchManagerClientInterface
+{
+ friend class PchManagerNotifierInterface;
+public:
+ void alive() override;
+ void precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message) override;
+
+ void precompiledHeaderRemoved(const QString &projectPartId);
+
+ void setConnectionClient(PchManagerConnectionClient *connectionClient);
+
+unitttest_public:
+ const std::vector<PchManagerNotifierInterface*> &notifiers() const;
+ void precompiledHeaderUpdated(const QString &projectPartId, const QString &pchFilePath);
+
+ void attach(PchManagerNotifierInterface *notifier);
+ void detach(PchManagerNotifierInterface *notifier);
+
+private:
+ std::vector<PchManagerNotifierInterface*> m_notifiers;
+ PchManagerConnectionClient *m_connectionClient=nullptr;
+};
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/pchmanagerconnectionclient.cpp b/src/plugins/clangpchmanager/pchmanagerconnectionclient.cpp
new file mode 100644
index 0000000000..9c4baa40c1
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagerconnectionclient.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "pchmanagerconnectionclient.h"
+
+#include <QCoreApplication>
+#include <QTemporaryDir>
+
+namespace ClangPchManager {
+
+namespace {
+
+QString currentProcessId()
+{
+ return QString::number(QCoreApplication::applicationPid());
+}
+
+}
+
+ClangPchManager::PchManagerConnectionClient::PchManagerConnectionClient(
+ ClangBackEnd::PchManagerClientInterface *client)
+ : serverProxy_(client, ioDevice())
+{
+ stdErrPrefixer().setPrefix("PchManagerConnectionClient.stderr: ");
+ stdOutPrefixer().setPrefix("PchManagerConnectionClient.stdout: ");
+}
+
+ClangBackEnd::PchManagerServerProxy &ClangPchManager::PchManagerConnectionClient::serverProxy()
+{
+ return serverProxy_;
+}
+
+void ClangPchManager::PchManagerConnectionClient::sendEndCommand()
+{
+ serverProxy_.end();
+}
+
+void PchManagerConnectionClient::resetCounter()
+{
+ serverProxy_.resetCounter();
+}
+
+QString ClangPchManager::PchManagerConnectionClient::connectionName() const
+{
+ return temporaryDirectory().path() + QStringLiteral("/ClangPchManagerBackEnd-") + currentProcessId();
+}
+
+QString PchManagerConnectionClient::outputName() const
+{
+ return QStringLiteral("PchManagerConnectionClient");
+}
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/pchmanagerconnectionclient.h b/src/plugins/clangpchmanager/pchmanagerconnectionclient.h
new file mode 100644
index 0000000000..72c04965e9
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagerconnectionclient.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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
+
+#include <connectionclient.h>
+#include <pchmanagerserverproxy.h>
+
+namespace ClangPchManager {
+
+class PchManagerConnectionClient : public ClangBackEnd::ConnectionClient
+{
+public:
+ PchManagerConnectionClient(ClangBackEnd::PchManagerClientInterface *client);
+
+ ClangBackEnd::PchManagerServerProxy &serverProxy();
+
+protected:
+ void sendEndCommand() override;
+ void resetCounter() override;
+ QString connectionName() const override;
+ QString outputName() const override;
+
+private:
+ ClangBackEnd::PchManagerServerProxy serverProxy_;
+};
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/pchmanagernotifierinterface.cpp b/src/plugins/clangpchmanager/pchmanagernotifierinterface.cpp
new file mode 100644
index 0000000000..f0524152ea
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagernotifierinterface.cpp
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "pchmanagernotifierinterface.h"
+
+#include <pchmanagerclient.h>
+
+namespace ClangPchManager {
+
+PchManagerNotifierInterface::PchManagerNotifierInterface(PchManagerClient &pchManagerClient)
+ : m_pchManagerClient(pchManagerClient)
+{
+ m_pchManagerClient.attach(this);
+}
+
+PchManagerNotifierInterface::~PchManagerNotifierInterface()
+{
+ m_pchManagerClient.detach(this);
+}
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/pchmanagernotifierinterface.h b/src/plugins/clangpchmanager/pchmanagernotifierinterface.h
new file mode 100644
index 0000000000..b10ceaab9d
--- /dev/null
+++ b/src/plugins/clangpchmanager/pchmanagernotifierinterface.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** 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
+
+#include <QtGlobal>
+
+QT_FORWARD_DECLARE_CLASS(QString)
+
+namespace ClangPchManager {
+
+class PchManagerClient;
+
+class PchManagerNotifierInterface
+{
+public:
+ PchManagerNotifierInterface(PchManagerClient &pchManagerClient);
+
+ virtual ~PchManagerNotifierInterface();
+ virtual void precompiledHeaderUpdated(const QString &projectPartId,
+ const QString &pchFilePath) = 0;
+ virtual void precompiledHeaderRemoved(const QString &projectPartId) = 0;
+
+ PchManagerClient &m_pchManagerClient;
+};
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/projectupdater.cpp b/src/plugins/clangpchmanager/projectupdater.cpp
new file mode 100644
index 0000000000..9e26fa7217
--- /dev/null
+++ b/src/plugins/clangpchmanager/projectupdater.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "projectupdater.h"
+
+#include "pchmanagerclient.h"
+
+#include <pchmanagerserverinterface.h>
+#include <removepchprojectpartsmessage.h>
+#include <updatepchprojectpartsmessage.h>
+
+#include <cpptools/clangcompileroptionsbuilder.h>
+#include <cpptools/projectpart.h>
+
+namespace ClangPchManager {
+
+ProjectUpdater::ProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
+ PchManagerClient &client)
+ : m_server(server),
+ m_client(client)
+{
+}
+
+void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts)
+{
+ ClangBackEnd::UpdatePchProjectPartsMessage message{toProjectPartContainers(projectParts)};
+
+ m_server.updatePchProjectParts(std::move(message));
+}
+
+void ProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
+{
+ ClangBackEnd::RemovePchProjectPartsMessage message{Utils::SmallStringVector(projectPartIds)};
+
+ m_server.removePchProjectParts(std::move(message));
+
+ for (const QString &projectPartiId : projectPartIds)
+ m_client.precompiledHeaderRemoved(projectPartiId);
+}
+
+namespace {
+class HeaderAndSources
+{
+public:
+ void reserve(std::size_t size)
+ {
+ headers.reserve(size);
+ sources.reserve(size);
+ }
+
+ Utils::SmallStringVector headers;
+ Utils::SmallStringVector sources;
+};
+
+HeaderAndSources headerAndSourcesFromProjectPart(CppTools::ProjectPart *projectPart)
+{
+ HeaderAndSources headerAndSources;
+ headerAndSources.reserve(std::size_t(projectPart->files.size()) * 3 / 2);
+
+ for (const CppTools::ProjectFile &projectFile : projectPart->files) {
+ if (projectFile.isSource())
+ headerAndSources.sources.push_back(projectFile.path);
+ else if (projectFile.isHeader())
+ headerAndSources.headers.push_back(projectFile.path);
+ }
+
+ return headerAndSources;
+}
+}
+
+ClangBackEnd::V2::ProjectPartContainer ProjectUpdater::toProjectPartContainer(CppTools::ProjectPart *projectPart)
+{
+ using CppTools::ClangCompilerOptionsBuilder;
+
+ QStringList arguments = ClangCompilerOptionsBuilder::build(
+ projectPart,
+ CppTools::ProjectFile::CXXHeader,
+ ClangCompilerOptionsBuilder::PchUsage::None,
+ CLANG_VERSION,
+ CLANG_RESOURCE_DIR);
+
+ HeaderAndSources headerAndSources = headerAndSourcesFromProjectPart(projectPart);
+
+ return ClangBackEnd::V2::ProjectPartContainer(projectPart->displayName,
+ Utils::SmallStringVector(arguments),
+ std::move(headerAndSources.headers),
+ std::move(headerAndSources.sources));
+}
+
+std::vector<ClangBackEnd::V2::ProjectPartContainer> ProjectUpdater::toProjectPartContainers(
+ std::vector<CppTools::ProjectPart *> projectParts)
+{
+ std::vector<ClangBackEnd::V2::ProjectPartContainer> projectPartContainers;
+ projectPartContainers.reserve(projectParts.size());
+
+ std::transform(projectParts.begin(),
+ projectParts.end(),
+ std::back_inserter(projectPartContainers),
+ ProjectUpdater::toProjectPartContainer);
+
+ return projectPartContainers;
+}
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/projectupdater.h b/src/plugins/clangpchmanager/projectupdater.h
new file mode 100644
index 0000000000..880920d1b7
--- /dev/null
+++ b/src/plugins/clangpchmanager/projectupdater.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** 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
+
+#include <clangpchmanager_global.h>
+
+namespace CppTools {
+class ProjectPart;
+}
+
+namespace ClangBackEnd {
+class PchManagerServerInterface;
+
+namespace V2 {
+class ProjectPartContainer;
+}
+}
+
+QT_FORWARD_DECLARE_CLASS(QStringList)
+
+#include <vector>
+
+namespace ClangPchManager {
+
+class PchManagerClient;
+
+class ProjectUpdater
+{
+public:
+ ProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
+ PchManagerClient &client);
+
+ void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts);
+ void removeProjectParts(const QStringList &projectPartIds);
+
+unittest_public:
+ static ClangBackEnd::V2::ProjectPartContainer toProjectPartContainer(
+ CppTools::ProjectPart *projectPart);
+ static std::vector<ClangBackEnd::V2::ProjectPartContainer> toProjectPartContainers(
+ std::vector<CppTools::ProjectPart *> projectParts);
+
+private:
+ ClangBackEnd::PchManagerServerInterface &m_server;
+ PchManagerClient &m_client;
+};
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp b/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
new file mode 100644
index 0000000000..48a6a287fc
--- /dev/null
+++ b/src/plugins/clangpchmanager/qtcreatorprojectupdater.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "qtcreatorprojectupdater.h"
+
+#include <cpptools/cppmodelmanager.h>
+
+#include <projectexplorer/project.h>
+
+namespace ClangPchManager {
+
+static CppTools::CppModelManager *cppModelManager()
+{
+ return CppTools::CppModelManager::instance();
+}
+
+QtCreatorProjectUpdater::QtCreatorProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
+ PchManagerClient &client)
+ : ProjectUpdater(server, client)
+{
+ connectToCppModelManager();
+}
+
+void QtCreatorProjectUpdater::projectPartsUpdated(ProjectExplorer::Project *project)
+{
+ const CppTools::ProjectInfo projectInfo = cppModelManager()->projectInfo(project);
+
+ const QVector<CppTools::ProjectPart::Ptr> projectPartSharedPointers = projectInfo.projectParts();
+
+ std::vector<CppTools::ProjectPart*> projectParts;
+ projectParts.reserve(std::size_t(projectPartSharedPointers.size()));
+
+ auto convertToRawPointer = [] (const CppTools::ProjectPart::Ptr &sharedPointer) {
+ return sharedPointer.data();
+ };
+
+ std::transform(projectPartSharedPointers.begin(),
+ projectPartSharedPointers.end(),
+ std::back_inserter(projectParts),
+ convertToRawPointer);
+
+ updateProjectParts(projectParts);
+}
+
+void QtCreatorProjectUpdater::projectPartsRemoved(const QStringList &projectPartIds)
+{
+ removeProjectParts(projectPartIds);
+}
+
+void QtCreatorProjectUpdater::connectToCppModelManager()
+{
+ connect(cppModelManager(),
+ &CppTools::CppModelManager::projectPartsUpdated,
+ this,
+ &QtCreatorProjectUpdater::projectPartsUpdated);
+ connect(cppModelManager(),
+ &CppTools::CppModelManager::projectPartsRemoved,
+ this,
+ &QtCreatorProjectUpdater::projectPartsRemoved);
+}
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangpchmanager/qtcreatorprojectupdater.h b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
new file mode 100644
index 0000000000..ec99eab50e
--- /dev/null
+++ b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** 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
+
+#include "projectupdater.h"
+
+#include <QObject>
+
+namespace ProjectExplorer {
+class Project;
+}
+
+namespace ClangPchManager {
+
+class QtCreatorProjectUpdater : public QObject, public ProjectUpdater
+{
+public:
+ QtCreatorProjectUpdater(ClangBackEnd::PchManagerServerInterface &server,
+ PchManagerClient &client);
+
+ void projectPartsUpdated(ProjectExplorer::Project *project);
+ void projectPartsRemoved(const QStringList &projectPartIds);
+
+private:
+ void connectToCppModelManager();
+};
+
+} // namespace ClangPchManager
diff --git a/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri b/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
index 7426f517e2..a10764be5b 100644
--- a/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
+++ b/src/plugins/clangrefactoring/clangrefactoring_dependencies.pri
@@ -5,5 +5,5 @@ QTC_LIB_DEPENDS += \
QTC_PLUGIN_DEPENDS += \
coreplugin \
cpptools \
- texteditor
-
+ texteditor \
+ clangpchmanager
diff --git a/src/plugins/clangrefactoring/refactoringclient.h b/src/plugins/clangrefactoring/refactoringclient.h
index 571214b2ee..82085458ff 100644
--- a/src/plugins/clangrefactoring/refactoringclient.h
+++ b/src/plugins/clangrefactoring/refactoringclient.h
@@ -45,14 +45,14 @@ namespace ClangRefactoring {
class RefactoringClient final : public ClangBackEnd::RefactoringClientInterface
{
public:
- void alive() final;
+ void alive() override;
void sourceLocationsForRenamingMessage(
- ClangBackEnd::SourceLocationsForRenamingMessage &&message) final;
+ ClangBackEnd::SourceLocationsForRenamingMessage &&message) override;
void sourceRangesAndDiagnosticsForQueryMessage(
- ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message) final;
+ ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage &&message) override;
void setLocalRenamingCallback(
- CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback) final;
+ CppTools::RefactoringEngineInterface::RenameCallback &&localRenamingCallback) override;
void setRefactoringEngine(ClangRefactoring::RefactoringEngine *refactoringEngine);
void setSearchHandle(ClangRefactoring::SearchHandle *searchHandleInterface);
ClangRefactoring::SearchHandle *searchHandle() const;
diff --git a/src/plugins/cpptools/cppprojectfile.cpp b/src/plugins/cpptools/cppprojectfile.cpp
index d1328b5bec..f2f6c6c1ba 100644
--- a/src/plugins/cpptools/cppprojectfile.cpp
+++ b/src/plugins/cpptools/cppprojectfile.cpp
@@ -109,6 +109,16 @@ bool ProjectFile::isSource(ProjectFile::Kind kind)
}
}
+bool ProjectFile::isHeader() const
+{
+ return isHeader(kind);
+}
+
+bool ProjectFile::isSource() const
+{
+ return isSource(kind);
+}
+
#define RETURN_TEXT_FOR_CASE(enumValue) case ProjectFile::enumValue: return #enumValue
static const char *projectFileKindToText(ProjectFile::Kind kind)
{
diff --git a/src/plugins/cpptools/cppprojectfile.h b/src/plugins/cpptools/cppprojectfile.h
index f6e2dde8cd..248ba8ac32 100644
--- a/src/plugins/cpptools/cppprojectfile.h
+++ b/src/plugins/cpptools/cppprojectfile.h
@@ -55,6 +55,9 @@ public:
static bool isHeader(Kind kind);
static bool isAmbiguousHeader(const QString &filePath);
+ bool isHeader() const;
+ bool isSource() const;
+
public:
ProjectFile() = default;
ProjectFile(const QString &filePath, Kind kind);
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 8090973537..2826ea3e2e 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -81,8 +81,9 @@ exists($$LLVM_INSTALL_DIR) {
win32-msvc2015:lessThan(QT_CL_PATCH_VERSION, 24210): QTC_NO_CLANG_LIBTOOLING = 1
isEmpty(QTC_NO_CLANG_LIBTOOLING) {
SUBDIRS += clangrefactoring
+ SUBDIRS += clangpchmanager
} else {
- warning("Building the Clang refactoring plugin is disabled.")
+ warning("Building the Clang refactoring and the pch manager plugins are disabled.")
}
} else {
warning("Set LLVM_INSTALL_DIR to build the Clang Code Model. " \
diff --git a/src/shared/clang/clang_installation.pri b/src/shared/clang/clang_installation.pri
index 1eb605a1cf..89a400045f 100644
--- a/src/shared/clang/clang_installation.pri
+++ b/src/shared/clang/clang_installation.pri
@@ -115,6 +115,7 @@ LLVM_CXXFLAGS ~= s,-O2,
LLVM_CXXFLAGS ~= s,/W4,
LLVM_CXXFLAGS ~= s,/EHc-,
LLVM_CXXFLAGS ~= s,-Werror=date-time,
+LLVM_CXXFLAGS ~= s,-fPIC,
# split-dwarf needs objcopy which does not work via icecc out-of-the-box
LLVM_CXXFLAGS ~= s,-gsplit-dwarf,
diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro b/src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro
new file mode 100644
index 0000000000..d3563c029e
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackend.pro
@@ -0,0 +1,34 @@
+QTC_LIB_DEPENDS += \
+ clangbackendipc
+
+include(../../qtcreatortool.pri)
+include(../../shared/clang/clang_installation.pri)
+include(source/clangpchmanagerbackend-source.pri)
+
+win32 {
+ LLVM_BUILDMODE = $$system($$llvm_config --build-mode, lines)
+ CONFIG(debug, debug|release):requires(equals(LLVM_BUILDMODE, "Debug"))
+}
+
+QT += core network
+QT -= gui
+
+LIBS += $$LIBTOOLING_LIBS
+INCLUDEPATH += $$LLVM_INCLUDEPATH
+
+QMAKE_CXXFLAGS += $$LLVM_CXXFLAGS
+
+INCLUDEPATH += ../clangrefactoringbackend/source
+
+SOURCES += \
+ clangpchmanagerbackendmain.cpp \
+ ../clangrefactoringbackend/source/clangtool.cpp \
+ ../clangrefactoringbackend/source/refactoringcompilationdatabase.cpp
+
+
+unix {
+ !macos: QMAKE_LFLAGS += -Wl,-z,origin
+ !disable_external_rpath: QMAKE_LFLAGS += -Wl,-rpath,$$shell_quote($${LLVM_LIBDIR})
+}
+
+DEFINES += CLANG_COMPILER_PATH=\"R\\\"xxx($$LLVM_INSTALL_DIR/bin/clang)xxx\\\"\"
diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
new file mode 100644
index 0000000000..929393116e
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include <clangpathwatcher.h>
+#include <connectionserver.h>
+#include <environment.h>
+#include <pchcreator.h>
+#include <pchmanagerserver.h>
+#include <pchmanagerclientproxy.h>
+#include <projectparts.h>
+#include <stringcache.h>
+
+#include <QCommandLineParser>
+#include <QCoreApplication>
+#include <QFileSystemWatcher>
+#include <QLoggingCategory>
+#include <QTemporaryDir>
+
+using ClangBackEnd::ClangPathWatcher;
+using ClangBackEnd::ConnectionServer;
+using ClangBackEnd::PchCreator;
+using ClangBackEnd::PchManagerClientProxy;
+using ClangBackEnd::PchManagerServer;
+using ClangBackEnd::ProjectParts;
+using ClangBackEnd::StringCache;
+
+class ApplicationEnvironment : public ClangBackEnd::Environment
+{
+public:
+ QString pchBuildDirectory() const override
+ {
+ return temporaryDirectory.path();
+ }
+
+ QString clangCompilerPath() const override
+ {
+ return QString(CLANG_COMPILER_PATH);
+ }
+
+private:
+ QTemporaryDir temporaryDirectory;
+};
+
+QString processArguments(QCoreApplication &application)
+{
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QStringLiteral("Qt Creator Clang PchManager Backend"));
+ parser.addHelpOption();
+ parser.addVersionOption();
+ parser.addPositionalArgument(QStringLiteral("connection"), QStringLiteral("Connection"));
+
+ parser.process(application);
+
+ if (parser.positionalArguments().isEmpty())
+ parser.showHelp(1);
+
+ return parser.positionalArguments().first();
+}
+
+int main(int argc, char *argv[])
+{
+ //QLoggingCategory::setFilterRules(QStringLiteral("*.debug=false"));
+
+ QCoreApplication::setOrganizationName(QStringLiteral("QtProject"));
+ QCoreApplication::setOrganizationDomain(QStringLiteral("qt-project.org"));
+ QCoreApplication::setApplicationName(QStringLiteral("ClangPchManagerBackend"));
+ QCoreApplication::setApplicationVersion(QStringLiteral("0.1.0"));
+
+ QCoreApplication application(argc, argv);
+
+ const QString connection = processArguments(application);
+
+ StringCache<Utils::SmallString> filePathCache;
+ ClangPathWatcher<QFileSystemWatcher> includeWatcher(filePathCache);
+ ApplicationEnvironment environment;
+ PchCreator pchCreator(environment, filePathCache);
+ ProjectParts projectParts;
+ PchManagerServer clangPchManagerServer(filePathCache, includeWatcher, pchCreator, projectParts);
+ ConnectionServer<PchManagerServer, PchManagerClientProxy> connectionServer(connection);
+ connectionServer.start();
+ connectionServer.setServer(&clangPchManagerServer);
+
+ return application.exec();
+}
+
+
diff --git a/src/tools/clangpchmanagerbackend/source/clangpathwatcher.cpp b/src/tools/clangpchmanagerbackend/source/clangpathwatcher.cpp
new file mode 100644
index 0000000000..1647fa7943
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/clangpathwatcher.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "clangpathwatcher.h"
+
+#include <utils/smallstringio.h>
+
+namespace ClangBackEnd {
+
+std::ostream &operator<<(std::ostream &out, const WatcherEntry &entry)
+{
+ out << "("
+ << entry.id << ", "
+ << entry.path
+ << ")";
+
+ return out;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h b/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h
new file mode 100644
index 0000000000..b3756ed2e5
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/clangpathwatcher.h
@@ -0,0 +1,392 @@
+/****************************************************************************
+**
+** 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
+
+#include "clangpathwatcherinterface.h"
+#include "clangpathwatchernotifier.h"
+#include "stringcache.h"
+
+#include <QObject>
+
+namespace ClangBackEnd {
+
+class WatcherEntry
+{
+public:
+ uint id;
+ uint path;
+
+ friend bool operator==(const WatcherEntry &first, const WatcherEntry &second)
+ {
+ return first.id == second.id && first.path == second.path;
+ }
+
+ friend bool operator<(const WatcherEntry &first, const WatcherEntry &second)
+ {
+ return std::tie(first.path, first.id) < std::tie(second.path, second.id);
+ }
+
+ friend bool operator<(const WatcherEntry &entry, uint path)
+ {
+ return entry.path < path;
+ }
+
+ friend bool operator<(uint path, const WatcherEntry &entry)
+ {
+ return path < entry.path;
+ }
+};
+
+template <typename FileSystemWatcher>
+class ClangPathWatcher : public ClangPathWatcherInterface
+{
+public:
+ ClangPathWatcher(StringCache<Utils::SmallString> &pathCache,
+ ClangPathWatcherNotifier *notifier=nullptr)
+ : m_pathCache(pathCache),
+ m_notifier(notifier)
+ {
+ QObject::connect(&m_fileSystemWatcher,
+ &FileSystemWatcher::fileChanged,
+ [&] (const QString &filePath) { addChangedPathForFilePath(filePath); });
+ }
+
+ void updateIdPaths(const std::vector<IdPaths> &idPaths) override
+ {
+ auto entriesAndIds = convertIdPathsToWatcherEntriesAndIds(idPaths);
+
+ addEntries(entriesAndIds.first);
+ removeUnusedEntries(entriesAndIds.first, entriesAndIds.second);
+ }
+
+ void removeIds(const Utils::SmallStringVector &ids) override
+ {
+ auto removedEntries = removeIdsFromWatchedEntries(convertToIdNumbers(ids));
+
+ auto filteredPaths = filterNotWatchedPaths(removedEntries);
+
+ if (!filteredPaths.empty())
+ m_fileSystemWatcher.removePaths(convertWatcherEntriesToQStringList(filteredPaths));
+ }
+
+ void setNotifier(ClangPathWatcherNotifier *notifier) override
+ {
+ m_notifier = notifier;
+ }
+
+unitttest_public:
+ static std::vector<uint> idsFromIdPaths(const std::vector<IdPaths> &idPaths)
+ {
+ std::vector<uint> ids;
+ ids.reserve(idPaths.size());
+
+ auto extractId = [] (const IdPaths &idPath) {
+ return idPath.id;
+ };
+
+ std::transform(idPaths.begin(),
+ idPaths.end(),
+ std::back_inserter(ids),
+ extractId);
+
+ std::sort(ids.begin(), ids.end());
+
+ return ids;
+ }
+
+ std::vector<uint> convertToIdNumbers(const Utils::SmallStringVector &ids)
+ {
+ std::vector<uint> idNumbers = m_idCache.stringIds(ids);
+
+ std::sort(idNumbers.begin(), idNumbers.end());
+
+ return idNumbers;
+ }
+
+ std::size_t sizeOfIdPaths(const std::vector<IdPaths> &idPaths)
+ {
+ auto sumSize = [] (std::size_t size, const IdPaths &idPath) {
+ return size + idPath.paths.size();
+ };
+
+ return std::accumulate(idPaths.begin(), idPaths.end(), 0u, sumSize);
+ }
+
+
+ std::pair<std::vector<WatcherEntry>,std::vector<uint>>
+ convertIdPathsToWatcherEntriesAndIds(const std::vector<IdPaths> &idPaths)
+ {
+ std::vector<WatcherEntry> entries;
+ entries.reserve(sizeOfIdPaths(idPaths));
+ std::vector<uint> ids;
+ ids.reserve(ids.size());
+
+ auto outputIterator = std::back_inserter(entries);
+
+ for (const IdPaths &idPath : idPaths)
+ {
+ uint id = m_idCache.stringId(idPath.id);
+
+ ids.push_back(id);
+
+ outputIterator = std::transform(idPath.paths.begin(),
+ idPath.paths.end(),
+ outputIterator,
+ [&] (uint path) { return WatcherEntry{id, path}; });
+ }
+
+ std::sort(entries.begin(), entries.end());
+ std::sort(ids.begin(), ids.end());
+
+ return {entries, ids};
+ }
+
+ void addEntries(const std::vector<WatcherEntry> &entries)
+ {
+ auto newEntries = notWatchedEntries(entries);
+
+ auto filteredPaths = filterNotWatchedPaths(newEntries);
+
+ mergeToWatchedEntries(newEntries);
+
+ if (!filteredPaths.empty())
+ m_fileSystemWatcher.addPaths(convertWatcherEntriesToQStringList(filteredPaths));
+ }
+
+ void removeUnusedEntries(const std::vector<WatcherEntry> &entries,
+ const std::vector<uint> &ids)
+ {
+ auto oldEntries = notAnymoreWatchedEntriesWithIds(entries, ids);
+
+ removeFromWatchedEntries(oldEntries);
+
+ auto filteredPaths = filterNotWatchedPaths(oldEntries);
+
+ if (!filteredPaths.empty())
+ m_fileSystemWatcher.removePaths(convertWatcherEntriesToQStringList(filteredPaths));
+ }
+
+ FileSystemWatcher &fileSystemWatcher()
+ {
+ return m_fileSystemWatcher;
+ }
+
+ QStringList convertWatcherEntriesToQStringList(
+ const std::vector<WatcherEntry> &watcherEntries)
+ {
+ QStringList paths;
+ paths.reserve(int(watcherEntries.size()));
+
+ std::transform(watcherEntries.begin(),
+ watcherEntries.end(),
+ std::back_inserter(paths),
+ [&] (const WatcherEntry &entry) { return m_pathCache.string(entry.path); });
+
+ return paths;
+ }
+
+ template <typename Compare>
+ std::vector<WatcherEntry> notWatchedEntries(const std::vector<WatcherEntry> &entries,
+ Compare compare) const
+ {
+ std::vector<WatcherEntry> notWatchedEntries;
+ notWatchedEntries.reserve(entries.size());
+
+ std::set_difference(entries.begin(),
+ entries.end(),
+ m_watchedEntries.cbegin(),
+ m_watchedEntries.cend(),
+ std::back_inserter(notWatchedEntries),
+ compare);
+
+ return notWatchedEntries;
+ }
+
+ std::vector<WatcherEntry> notWatchedEntries(const std::vector<WatcherEntry> &entries) const
+ {
+ return notWatchedEntries(entries, std::less<WatcherEntry>());
+ }
+
+ std::vector<WatcherEntry> notWatchedPaths(const std::vector<WatcherEntry> &entries) const
+ {
+ auto compare = [] (const WatcherEntry &first, const WatcherEntry &second) {
+ return first.path < second.path;
+ };
+
+ return notWatchedEntries(entries, compare);
+ }
+
+ template <typename Compare>
+ std::vector<WatcherEntry> notAnymoreWatchedEntries(
+ const std::vector<WatcherEntry> &newEntries,
+ Compare compare) const
+ {
+ std::vector<WatcherEntry> notAnymoreWatchedEntries;
+ notAnymoreWatchedEntries.reserve(m_watchedEntries.size());
+
+ std::set_difference(m_watchedEntries.cbegin(),
+ m_watchedEntries.cend(),
+ newEntries.begin(),
+ newEntries.end(),
+ std::back_inserter(notAnymoreWatchedEntries),
+ compare);
+
+ return notAnymoreWatchedEntries;
+ }
+
+ std::vector<WatcherEntry> notAnymoreWatchedEntriesWithIds(
+ const std::vector<WatcherEntry> &newEntries,
+ const std::vector<uint> &ids) const
+ {
+ auto oldEntries = notAnymoreWatchedEntries(newEntries, std::less<WatcherEntry>());
+
+ auto newEnd = std::remove_if(oldEntries.begin(),
+ oldEntries.end(),
+ [&] (WatcherEntry entry) {
+ return !std::binary_search(ids.begin(), ids.end(), entry.id);
+ });
+
+ oldEntries.erase(newEnd, oldEntries.end());
+
+ return oldEntries;
+ }
+
+ void mergeToWatchedEntries(const std::vector<WatcherEntry> &newEntries)
+ {
+ std::vector<WatcherEntry> newWatchedEntries;
+ newWatchedEntries.reserve(m_watchedEntries.size() + newEntries.size());
+
+ std::merge(m_watchedEntries.cbegin(),
+ m_watchedEntries.cend(),
+ newEntries.begin(),
+ newEntries.end(),
+ std::back_inserter(newWatchedEntries));
+
+ m_watchedEntries = std::move(newWatchedEntries);
+ }
+
+ static
+ std::vector<WatcherEntry> uniquePaths(const std::vector<WatcherEntry> &pathEntries)
+ {
+ std::vector<WatcherEntry> uniqueEntries;
+
+ auto compare = [] (const WatcherEntry &first, const WatcherEntry &second) {
+ return first.path == second.path;
+ };
+
+ std::unique_copy(pathEntries.begin(),
+ pathEntries.end(),
+ std::back_inserter(uniqueEntries),
+ compare);
+
+ return uniqueEntries;
+ }
+
+ std::vector<WatcherEntry> filterNotWatchedPaths(const std::vector<WatcherEntry> &entries)
+ {
+ return notWatchedPaths(uniquePaths(entries));
+ }
+
+ const std::vector<WatcherEntry> &watchedEntries() const
+ {
+ return m_watchedEntries;
+ }
+
+ std::vector<WatcherEntry> removeIdsFromWatchedEntries(const std::vector<uint> &ids)
+ {
+
+ auto keep = [&] (const WatcherEntry &entry) {
+ return !std::binary_search(ids.begin(), ids.end(), entry.id);
+ };
+
+ auto found = std::stable_partition(m_watchedEntries.begin(),
+ m_watchedEntries.end(),
+ keep);
+
+ std::vector<WatcherEntry> removedEntries(found, m_watchedEntries.end());
+
+ m_watchedEntries.erase(found, m_watchedEntries.end());
+
+ return removedEntries;
+ }
+
+ void removeFromWatchedEntries(const std::vector<WatcherEntry> &oldEntries)
+ {
+ std::vector<WatcherEntry> newWatchedEntries;
+ newWatchedEntries.reserve(m_watchedEntries.size() - oldEntries.size());
+
+ std::set_difference(m_watchedEntries.cbegin(),
+ m_watchedEntries.cend(),
+ oldEntries.begin(),
+ oldEntries.end(),
+ std::back_inserter(newWatchedEntries));
+
+
+ m_watchedEntries = newWatchedEntries;
+ }
+
+ void addChangedPathForFilePath(const QString &filePath)
+ {
+ uint pathId = m_pathCache.stringId(Utils::SmallString(filePath));
+
+ auto range = std::equal_range(m_watchedEntries.begin(), m_watchedEntries.end(), pathId);
+
+ Utils::SmallStringVector changedIds;
+
+ std::transform(range.first,
+ range.second,
+ std::back_inserter(changedIds),
+ [&] (const WatcherEntry &entry) {
+ return m_idCache.string(entry.id);
+ });
+
+ std::sort(changedIds.begin(), changedIds.end());
+
+ if (m_notifier)
+ m_notifier->pathsWithIdsChanged(changedIds);
+ }
+
+ StringCache<Utils::SmallString> &pathCache()
+ {
+ return m_pathCache;
+ }
+
+ StringCache<Utils::SmallString> &idCache()
+ {
+ return m_idCache;
+ }
+
+private:
+ StringCache<Utils::SmallString> m_idCache;
+ std::vector<WatcherEntry> m_watchedEntries;
+ FileSystemWatcher m_fileSystemWatcher;
+ StringCache<Utils::SmallString> &m_pathCache;
+ ClangPathWatcherNotifier *m_notifier;
+};
+
+std::ostream &operator<<(std::ostream &out, const WatcherEntry &entry);
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/clangpathwatcherinterface.cpp b/src/tools/clangpchmanagerbackend/source/clangpathwatcherinterface.cpp
new file mode 100644
index 0000000000..7862f4d0fd
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/clangpathwatcherinterface.cpp
@@ -0,0 +1,35 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "clangpathwatcherinterface.h"
+
+namespace ClangBackEnd {
+
+ClangPathWatcherInterface::~ClangPathWatcherInterface()
+{
+
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/clangpathwatcherinterface.h b/src/tools/clangpchmanagerbackend/source/clangpathwatcherinterface.h
new file mode 100644
index 0000000000..fbd1776e5c
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/clangpathwatcherinterface.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** 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
+
+#include "idpaths.h"
+
+#include <utils/smallstringvector.h>
+
+namespace ClangBackEnd {
+
+class ClangPathWatcherNotifier;
+
+class ClangPathWatcherInterface
+{
+public:
+ virtual ~ClangPathWatcherInterface();
+
+ virtual void updateIdPaths(const std::vector<IdPaths> &idPaths) = 0;
+ virtual void removeIds(const Utils::SmallStringVector &ids) = 0;
+
+ virtual void setNotifier(ClangPathWatcherNotifier *notifier) = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/clangpathwatchernotifier.cpp b/src/tools/clangpchmanagerbackend/source/clangpathwatchernotifier.cpp
new file mode 100644
index 0000000000..66f6b3534f
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/clangpathwatchernotifier.cpp
@@ -0,0 +1,35 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "clangpathwatchernotifier.h"
+
+namespace ClangBackEnd {
+
+ClangPathWatcherNotifier::~ClangPathWatcherNotifier()
+{
+
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/clangpathwatchernotifier.h b/src/tools/clangpchmanagerbackend/source/clangpathwatchernotifier.h
new file mode 100644
index 0000000000..c95ab56e51
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/clangpathwatchernotifier.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** 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
+
+#include <utils/smallstringvector.h>
+
+namespace ClangBackEnd {
+
+class ClangPathWatcherNotifier
+{
+public:
+ virtual ~ClangPathWatcherNotifier();
+
+ virtual void pathsWithIdsChanged(const Utils::SmallStringVector &ids) = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
new file mode 100644
index 0000000000..696159245b
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
@@ -0,0 +1,32 @@
+INCLUDEPATH += $$PWD
+
+SOURCES += \
+ $$PWD/includecollector.cpp \
+ $$PWD/pchmanagerserver.cpp \
+ $$PWD/pchcreator.cpp \
+ $$PWD/clangpathwatcher.cpp \
+ $$PWD/projectparts.cpp \
+ $$PWD/idpaths.cpp \
+ $$PWD/pchcreatorinterface.cpp \
+ $$PWD/clangpathwatcherinterface.cpp \
+ $$PWD/projectpartsinterface.cpp \
+ $$PWD/clangpathwatchernotifier.cpp
+
+HEADERS += \
+ $$PWD/clangpchmanagerbackend_global.h \
+ $$PWD/includecollector.h \
+ $$PWD/collectincludestoolaction.h \
+ $$PWD/collectincludesaction.h \
+ $$PWD/collectincludespreprocessorcallbacks.h \
+ $$PWD/pchmanagerserver.h \
+ $$PWD/pchcreator.h \
+ $$PWD/pchnotcreatederror.h \
+ $$PWD/environment.h \
+ $$PWD/clangpathwatcher.h \
+ $$PWD/projectparts.h \
+ $$PWD/stringcache.h \
+ $$PWD/idpaths.h \
+ $$PWD/pchcreatorinterface.h \
+ $$PWD/clangpathwatcherinterface.h \
+ $$PWD/projectpartsinterface.h \
+ $$PWD/clangpathwatchernotifier.h
diff --git a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend_global.h b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend_global.h
new file mode 100644
index 0000000000..57fa8c64f8
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend_global.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** 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
+
+#ifdef UNIT_TESTS
+#define unitttest_public public
+#else
+#define unitttest_public private
+#endif
+
+namespace llvm {
+template <typename T, unsigned N>
+class SmallVector;
+}
+
+using uint = unsigned int;
+
+namespace Utils {
+template <uint Size>
+class BasicSmallString;
+using SmallString = BasicSmallString<31>;
+using PathString = BasicSmallString<191>;
+}
+
+namespace ClangBackEnd {
+
+using USRName = llvm::SmallVector<char, 128>;
+
+}
diff --git a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h b/src/tools/clangpchmanagerbackend/source/collectincludesaction.h
new file mode 100644
index 0000000000..3f98b307e1
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/collectincludesaction.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** 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
+
+#include "stringcache.h"
+
+#include <collectincludespreprocessorcallbacks.h>
+
+#include <clang/Frontend/FrontendActions.h>
+#include <clang/Frontend/CompilerInstance.h>
+#include <clang/Lex/Preprocessor.h>
+
+namespace ClangBackEnd {
+
+class CollectIncludesAction final : public clang::PreprocessOnlyAction
+{
+public:
+ CollectIncludesAction(std::vector<uint> &includeIds,
+ StringCache<Utils::SmallString> &filePathCache,
+ const std::vector<uint> &excludedIncludeUID,
+ std::vector<uint> &alreadyIncludedFileUIDs)
+ : m_includeIds(includeIds),
+ m_filePathCache(filePathCache),
+ m_excludedIncludeUID(excludedIncludeUID),
+ m_alreadyIncludedFileUIDs(alreadyIncludedFileUIDs)
+ {
+ }
+
+ bool BeginSourceFileAction(clang::CompilerInstance &compilerInstance,
+ llvm::StringRef filename) override
+ {
+ if (clang::PreprocessOnlyAction::BeginSourceFileAction(compilerInstance, filename)) {
+ auto &preprocessor = compilerInstance.getPreprocessor();
+ auto &headerSearch = preprocessor.getHeaderSearchInfo();
+
+ auto macroPreprocessorCallbacks = new CollectIncludesPreprocessorCallbacks(headerSearch,
+ m_includeIds,
+ m_filePathCache,
+ m_excludedIncludeUID,
+ m_alreadyIncludedFileUIDs);
+
+ preprocessor.addPPCallbacks(std::unique_ptr<clang::PPCallbacks>(macroPreprocessorCallbacks));
+
+ return true;
+ }
+
+ return false;
+ }
+
+ void EndSourceFileAction() override
+ {
+ clang::PreprocessOnlyAction::EndSourceFileAction();
+ }
+
+private:
+ std::vector<uint> &m_includeIds;
+ StringCache<Utils::SmallString> &m_filePathCache;
+ const std::vector<uint> &m_excludedIncludeUID;
+ std::vector<uint> &m_alreadyIncludedFileUIDs;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h
new file mode 100644
index 0000000000..4dbf0d9758
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** 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
+
+#include "stringcache.h"
+
+#include <clang/Basic/SourceManager.h>
+#include <clang/Lex/MacroInfo.h>
+#include <clang/Lex/HeaderSearch.h>
+#include <clang/Lex/PPCallbacks.h>
+#include <clang/Lex/Preprocessor.h>
+
+#include <utils/smallstringvector.h>
+
+#include <algorithm>
+
+namespace ClangBackEnd {
+
+class CollectIncludesPreprocessorCallbacks final : public clang::PPCallbacks
+{
+public:
+ CollectIncludesPreprocessorCallbacks(clang::HeaderSearch &headerSearch,
+ std::vector<uint> &includeIds,
+ StringCache<Utils::SmallString> &filePathCache,
+ const std::vector<uint> &excludedIncludeUID,
+ std::vector<uint> &alreadyIncludedFileUIDs)
+ : m_headerSearch(headerSearch),
+ m_includeIds(includeIds),
+ m_filePathCache(filePathCache),
+ m_excludedIncludeUID(excludedIncludeUID),
+ m_alreadyIncludedFileUIDs(alreadyIncludedFileUIDs)
+ {}
+
+ void InclusionDirective(clang::SourceLocation /*hashLocation*/,
+ const clang::Token &/*includeToken*/,
+ llvm::StringRef fileName,
+ bool /*isAngled*/,
+ clang::CharSourceRange /*fileNameRange*/,
+ const clang::FileEntry *file,
+ llvm::StringRef /*searchPath*/,
+ llvm::StringRef /*relativePath*/,
+ const clang::Module */*imported*/) override
+ {
+ auto fileUID = file->getUID();
+
+ flagIncludeAlreadyRead(file);
+
+ if (isNotInExcludedIncludeUID(fileUID)) {
+ auto notAlreadyIncluded = isNotAlreadyIncluded(fileUID);
+ if (notAlreadyIncluded.first) {
+ m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID);
+ uint includeId = m_filePathCache.stringId({fileName.data(), fileName.size()});
+ m_includeIds.emplace_back(includeId);
+ }
+ }
+ }
+
+ bool isNotInExcludedIncludeUID(uint uid) const
+ {
+ return !std::binary_search(m_excludedIncludeUID.begin(),
+ m_excludedIncludeUID.end(),
+ uid);
+ }
+
+ std::pair<bool, std::vector<uint>::iterator> isNotAlreadyIncluded(uint uid) const
+ {
+ auto range = std::equal_range(m_alreadyIncludedFileUIDs.begin(),
+ m_alreadyIncludedFileUIDs.end(),
+ uid);
+
+ return {range.first == range.second, range.first};
+ }
+
+ void flagIncludeAlreadyRead(const clang::FileEntry *file)
+ {
+ auto &headerFileInfo = m_headerSearch.getFileInfo(file);
+
+ headerFileInfo.isImport = true;
+ ++headerFileInfo.NumIncludes;
+
+ }
+
+private:
+ clang::HeaderSearch &m_headerSearch;
+ std::vector<uint> &m_includeIds;
+ StringCache<Utils::SmallString> &m_filePathCache;
+ const std::vector<uint> &m_excludedIncludeUID;
+ std::vector<uint> &m_alreadyIncludedFileUIDs;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h b/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h
new file mode 100644
index 0000000000..f8b9f28a83
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** 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
+
+#include "stringcache.h"
+
+#include "collectincludesaction.h"
+
+#include <clang/Tooling/Tooling.h>
+
+namespace ClangBackEnd {
+
+class CollectIncludesToolAction final : public clang::tooling::FrontendActionFactory
+{
+public:
+ CollectIncludesToolAction(std::vector<uint> &includeIds,
+ StringCache<Utils::SmallString> &filePathCache,
+ const std::vector<uint> &excludedIncludeUIDs)
+ : m_includeIds(includeIds),
+ m_filePathCache(filePathCache),
+ m_excludedIncludeUIDs(excludedIncludeUIDs)
+ {}
+
+ clang::FrontendAction *create()
+ {
+ return new CollectIncludesAction(m_includeIds,
+ m_filePathCache,
+ m_excludedIncludeUIDs,
+ m_alreadyIncludedFileUIDs);
+ }
+
+private:
+ std::vector<uint> m_alreadyIncludedFileUIDs;
+ std::vector<uint> &m_includeIds;
+ StringCache<Utils::SmallString> &m_filePathCache;
+ const std::vector<uint> &m_excludedIncludeUIDs;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/environment.h b/src/tools/clangpchmanagerbackend/source/environment.h
new file mode 100644
index 0000000000..4fe7442c17
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/environment.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+**
+** 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
+
+#include <QString>
+
+namespace ClangBackEnd {
+
+class Environment
+{
+public:
+ virtual QString pchBuildDirectory() const = 0;
+ virtual QString clangCompilerPath() const = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/idpaths.cpp b/src/tools/clangpchmanagerbackend/source/idpaths.cpp
new file mode 100644
index 0000000000..f1dba02e4e
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/idpaths.cpp
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "idpaths.h"
+
+#include <utils/smallstringio.h>
+
+namespace ClangBackEnd {
+
+std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths)
+{
+ out << "("
+ << idPaths.id << ", "
+ << idPaths.paths << ")";
+
+ return out;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/idpaths.h b/src/tools/clangpchmanagerbackend/source/idpaths.h
new file mode 100644
index 0000000000..f6f312f05f
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/idpaths.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** 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
+
+#include <utils/smallstring.h>
+
+#include <iosfwd>
+
+namespace ClangBackEnd {
+
+class IdPaths
+{
+public:
+ Utils::SmallString id;
+ std::vector<uint> paths;
+
+ friend bool operator==(const IdPaths &first, const IdPaths &second)
+ {
+ return first.id == second.id && first.paths == second.paths;
+ }
+};
+
+std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths);
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.cpp b/src/tools/clangpchmanagerbackend/source/includecollector.cpp
new file mode 100644
index 0000000000..f383af9609
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/includecollector.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "includecollector.h"
+
+#include "collectincludestoolaction.h"
+
+#include <utils/smallstring.h>
+
+namespace ClangBackEnd {
+
+IncludeCollector::IncludeCollector(StringCache<Utils::SmallString> &filePathCache)
+ : m_filePathCache(filePathCache)
+{
+}
+
+void IncludeCollector::collectIncludes()
+{
+ clang::tooling::ClangTool tool = createTool();
+
+ auto excludedIncludeFileUIDs = generateExcludedIncludeFileUIDs(tool.getFiles());
+
+ auto action = std::unique_ptr<CollectIncludesToolAction>(
+ new CollectIncludesToolAction(m_includeIds, m_filePathCache, excludedIncludeFileUIDs));
+
+ tool.run(action.get());
+}
+
+void IncludeCollector::setExcludedIncludes(Utils::SmallStringVector &&excludedIncludes)
+{
+ this->m_excludedIncludes = std::move(excludedIncludes);
+}
+
+std::vector<uint> IncludeCollector::takeIncludeIds()
+{
+ std::sort(m_includeIds.begin(), m_includeIds.end());
+
+ return std::move(m_includeIds);
+}
+
+std::vector<uint> IncludeCollector::generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const
+{
+ std::vector<uint> fileUIDs;
+ fileUIDs.reserve(m_excludedIncludes.size());
+
+ auto generateUID = [&] (const Utils::SmallString &filePath) {
+ return fileManager.getFile({filePath.data(), filePath.size()})->getUID();
+ };
+
+ std::transform(m_excludedIncludes.begin(),
+ m_excludedIncludes.end(),
+ std::back_inserter(fileUIDs),
+ generateUID);
+
+ std::sort(fileUIDs.begin(), fileUIDs.end());
+
+ return fileUIDs;
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.h b/src/tools/clangpchmanagerbackend/source/includecollector.h
new file mode 100644
index 0000000000..15914c22a2
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/includecollector.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** 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
+
+#include "stringcache.h"
+
+#include <clangtool.h>
+
+namespace ClangBackEnd {
+
+class IncludeCollector : public ClangTool
+{
+public:
+ IncludeCollector(StringCache<Utils::SmallString> &filePathCache);
+
+ void collectIncludes();
+
+ void setExcludedIncludes(Utils::SmallStringVector &&excludedIncludes);
+
+ std::vector<uint> takeIncludeIds();
+
+private:
+ std::vector<uint> generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const;
+
+private:
+ Utils::SmallStringVector m_excludedIncludes;
+ std::vector<uint> m_includeIds;
+ Utils::SmallStringVector m_directories;
+ StringCache<Utils::SmallString> &m_filePathCache;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
new file mode 100644
index 0000000000..560e6a2bb5
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
@@ -0,0 +1,518 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "pchcreator.h"
+
+#include "environment.h"
+#include "includecollector.h"
+#include "pchnotcreatederror.h"
+
+#include <projectpartpch.h>
+
+#include <QCryptographicHash>
+#include <QFile>
+#include <QProcess>
+
+namespace ClangBackEnd {
+
+PchCreator::PchCreator(Environment &environment, StringCache<Utils::SmallString> &filePathCache)
+ : m_environment(environment),
+ m_filePathCache(filePathCache)
+{
+}
+
+PchCreator::PchCreator(V2::ProjectPartContainers &&projectsParts,
+ Environment &environment,
+ StringCache<Utils::SmallString> &filePathCache)
+ : m_projectParts(std::move(projectsParts)),
+ m_environment(environment),
+ m_filePathCache(filePathCache)
+{
+}
+
+namespace {
+template <typename Source,
+ typename Target>
+void append(Target &target, const Source &source)
+{
+ Source clonedSource = source.clone();
+
+ target.reserve(target.size() + source.size());
+
+ std::move(clonedSource.begin(),
+ clonedSource.end(),
+ std::back_inserter(target));
+}
+
+template <typename Source,
+ typename Target>
+void append(Target &target, Source &source)
+{
+ target.reserve(target.size() + source.size());
+
+ std::move(source.begin(),
+ source.end(),
+ std::back_inserter(target));
+}
+
+template <typename GetterFunction>
+std::size_t globalCount(const V2::ProjectPartContainers &projectsParts,
+ GetterFunction getterFunction)
+{
+ auto sizeFunction = [&] (std::size_t size, const V2::ProjectPartContainer &projectContainer) {
+ return size + getterFunction(projectContainer).size();
+ };
+
+ return std::accumulate(projectsParts.begin(),
+ projectsParts.end(),
+ std::size_t(0),
+ sizeFunction);
+}
+
+template <typename GetterFunction>
+void generateGlobal(Utils::SmallStringVector &entries,
+ const V2::ProjectPartContainers &projectsParts,
+ GetterFunction getterFunction)
+{
+ entries.reserve(entries.size() + globalCount(projectsParts, getterFunction));
+
+ for (const V2::ProjectPartContainer &projectPart : projectsParts) {
+ const auto &projectPartPaths = getterFunction(projectPart);
+
+ append(entries, projectPartPaths);
+ };
+}
+
+template <typename GetterFunction>
+Utils::SmallStringVector generateGlobal(
+ const V2::ProjectPartContainers &projectsParts,
+ GetterFunction getterFunction)
+{
+ Utils::SmallStringVector entries;
+
+ generateGlobal(entries, projectsParts, getterFunction);
+
+ return entries;
+}
+
+}
+
+Utils::SmallStringVector PchCreator::generateGlobalHeaderPaths() const
+{
+ auto includeFunction = [] (const V2::ProjectPartContainer &projectPart)
+ -> const Utils::SmallStringVector & {
+ return projectPart.headerPaths();
+ };
+
+ return generateGlobal(m_projectParts, includeFunction);
+}
+
+Utils::SmallStringVector PchCreator::generateGlobalSourcePaths() const
+{
+ auto sourceFunction = [] (const V2::ProjectPartContainer &projectPart)
+ -> const Utils::SmallStringVector & {
+ return projectPart.sourcePaths();
+ };
+
+ return generateGlobal(m_projectParts, sourceFunction);
+}
+
+Utils::SmallStringVector PchCreator::generateGlobalHeaderAndSourcePaths() const
+{
+ const auto &sourcePaths = generateGlobalSourcePaths();
+ auto includePaths = generateGlobalHeaderPaths();
+
+ append(includePaths, sourcePaths);
+
+ return includePaths;
+}
+
+Utils::SmallStringVector PchCreator::generateGlobalArguments() const
+{
+ Utils::SmallStringVector arguments;
+
+ auto argumentFunction = [] (const V2::ProjectPartContainer &projectPart)
+ -> const Utils::SmallStringVector & {
+ return projectPart.arguments();
+ };
+
+ generateGlobal(arguments, m_projectParts, argumentFunction);
+
+ return arguments;
+}
+
+Utils::SmallStringVector PchCreator::generateGlobalCommandLine() const
+{
+ Utils::SmallStringVector commandLine;
+ commandLine.emplace_back(m_environment.clangCompilerPath());
+
+ auto argumentFunction = [] (const V2::ProjectPartContainer &projectPart)
+ -> const Utils::SmallStringVector & {
+ return projectPart.arguments();
+ };
+
+ generateGlobal(commandLine, m_projectParts, argumentFunction);
+
+ return commandLine;
+}
+
+Utils::SmallStringVector PchCreator::generateGlobalPchCompilerArguments() const
+{
+ Utils::SmallStringVector arguments;
+ arguments.reserve(5);
+
+ arguments.emplace_back("-x");
+ arguments.emplace_back("c++-header");
+ arguments.emplace_back("-Xclang");
+ arguments.emplace_back("-emit-pch");
+ arguments.emplace_back("-o");
+ arguments.emplace_back(generateGlobalPchFilePath());
+ arguments.emplace_back(generateGlobalPchHeaderFilePath());
+
+ return arguments;
+}
+
+Utils::SmallStringVector PchCreator::generateGlobalClangCompilerArguments() const
+{
+ auto compilerArguments = generateGlobalArguments();
+ const auto pchArguments = generateGlobalPchCompilerArguments();
+
+ append(compilerArguments, pchArguments);
+
+ return compilerArguments;
+}
+
+std::vector<uint> PchCreator::generateGlobalPchIncludeIds() const
+{
+ IncludeCollector collector(m_filePathCache);
+
+ collector.setExcludedIncludes(generateGlobalHeaderPaths());
+
+ collector.addFiles(generateGlobalHeaderAndSourcePaths(), generateGlobalCommandLine());
+
+ collector.collectIncludes();
+
+ return collector.takeIncludeIds();
+}
+
+namespace {
+
+std::size_t contentSize(const std::vector<Utils::SmallString> &includes)
+{
+ auto countIncludeSize = [] (std::size_t size, const Utils::SmallString &include) {
+ return size + include.size();
+ };
+
+ return std::accumulate(includes.begin(), includes.end(), std::size_t(0), countIncludeSize);
+}
+}
+
+Utils::SmallString PchCreator::generatePchIncludeFileContent(
+ const std::vector<uint> &includeIds) const
+{
+ Utils::SmallString fileContent;
+ const std::size_t lineTemplateSize = 12;
+ auto includes = m_filePathCache.strings(includeIds);
+
+ fileContent.reserve(includes.size() * lineTemplateSize + contentSize(includes));
+
+ for (const Utils::SmallString &include : includes) {
+ fileContent += "#include <";
+ fileContent += include;
+ fileContent += ">\n";
+ }
+
+ return fileContent;
+}
+
+Utils::SmallString PchCreator::generateGlobalPchHeaderFileContent() const
+{
+ return generatePchIncludeFileContent(generateGlobalPchIncludeIds());
+}
+
+std::unique_ptr<QFile> PchCreator::generateGlobalPchHeaderFile()
+{
+ return generatePchHeaderFile(generateGlobalPchHeaderFilePath(),
+ generateGlobalPchHeaderFileContent());
+}
+
+void PchCreator::generatePch(const Utils::SmallStringVector &clangCompilerArguments)
+{
+ QProcess process;
+ process.setProcessChannelMode(QProcess::ForwardedChannels);
+
+ process.start(m_environment.clangCompilerPath(),
+ convertToQStringList(clangCompilerArguments));
+ process.waitForFinished(100000);
+
+ checkIfProcessHasError(process);
+}
+
+void PchCreator::generateGlobalPch()
+{
+ generateGlobalPchHeaderFile();
+
+ generatePch(generateGlobalClangCompilerArguments());
+}
+
+QStringList PchCreator::convertToQStringList(const Utils::SmallStringVector &compilerArguments)
+{
+ QStringList qStringList;
+
+ append(qStringList, compilerArguments);
+
+ return qStringList;
+}
+
+namespace {
+
+void hashProjectPart(QCryptographicHash &hash, const V2::ProjectPartContainer &projectPart)
+{
+ const auto &projectPartId = projectPart.projectPartId();
+ hash.addData(projectPartId.data(), projectPartId.size());
+
+ for (const auto &argument : projectPart.arguments())
+ hash.addData(argument.data(), argument.size());
+}
+}
+
+QByteArray PchCreator::globalProjectHash() const
+{
+ QCryptographicHash hash(QCryptographicHash::Sha1);
+
+ for (const auto &projectPart : m_projectParts)
+ hashProjectPart(hash, projectPart);
+
+ auto result = hash.result();
+
+ return result.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
+}
+
+void PchCreator::checkIfProcessHasError(const QProcess &process)
+{
+ if (process.exitCode()) {
+ const std::string errorString = process.errorString().toStdString();
+ throw PchNotCreatedError(errorString);
+ }
+}
+
+Utils::SmallString PchCreator::generateGlobalPchFilePathWithoutExtension() const
+{
+ QByteArray fileName = m_environment.pchBuildDirectory().toUtf8();
+ fileName += '/';
+ fileName += globalProjectHash();
+
+ return Utils::SmallString::fromQByteArray(fileName);
+}
+
+Utils::SmallString PchCreator::generateGlobalPchHeaderFilePath() const
+{
+ Utils::SmallString filePath = generateGlobalPchFilePathWithoutExtension();
+
+ filePath += ".h";
+
+ return filePath;
+}
+
+Utils::SmallString PchCreator::generateGlobalPchFilePath() const
+{
+ Utils::SmallString filePath = generateGlobalPchFilePathWithoutExtension();
+
+ filePath += ".pch";
+
+ return filePath;
+}
+
+Utils::SmallStringVector PchCreator::generateProjectPartCommandLine(
+ const V2::ProjectPartContainer &projectPart) const
+{
+ const Utils::SmallStringVector &arguments = projectPart.arguments();
+
+ Utils::SmallStringVector commandLine;
+ commandLine.reserve(arguments.size() + 1);
+
+ commandLine.emplace_back(m_environment.clangCompilerPath());
+
+ append(commandLine , arguments);
+
+ return commandLine;
+}
+
+Utils::SmallString PchCreator::generateProjectPartPchFilePathWithoutExtension(
+ const V2::ProjectPartContainer &projectPart) const
+{
+ QByteArray fileName = m_environment.pchBuildDirectory().toUtf8();
+ fileName += '/';
+ fileName += projectPartHash(projectPart);
+
+ return Utils::SmallString::fromQByteArray(fileName);
+}
+
+Utils::SmallStringVector PchCreator::generateProjectPartHeaderAndSourcePaths(
+ const V2::ProjectPartContainer &projectPart)
+{
+ Utils::SmallStringVector includeAndSources;
+ includeAndSources.reserve(projectPart.headerPaths().size() + projectPart.sourcePaths().size());
+
+ append(includeAndSources, projectPart.headerPaths());
+ append(includeAndSources, projectPart.sourcePaths());
+
+ return includeAndSources;
+}
+
+std::vector<uint> PchCreator::generateProjectPartPchIncludes(
+ const V2::ProjectPartContainer &projectPart) const
+{
+ IncludeCollector collector(m_filePathCache);
+
+ collector.setExcludedIncludes(projectPart.headerPaths().clone());
+
+ collector.addFiles(generateProjectPartHeaderAndSourcePaths(projectPart),
+ generateProjectPartCommandLine(projectPart));
+
+ collector.collectIncludes();
+
+ return collector.takeIncludeIds();
+}
+
+Utils::SmallString PchCreator::generateProjectPathPchHeaderFilePath(
+ const V2::ProjectPartContainer &projectPart) const
+{
+ Utils::SmallString filePath = generateProjectPartPchFilePathWithoutExtension(projectPart);
+
+ filePath += ".h";
+
+ return filePath;
+}
+
+Utils::SmallString PchCreator::generateProjectPartPchFilePath(
+ const V2::ProjectPartContainer &projectPart) const
+{
+ Utils::SmallString filePath = generateProjectPartPchFilePathWithoutExtension(projectPart);
+
+ filePath += ".pch";
+
+ return filePath;
+}
+
+Utils::SmallStringVector PchCreator::generateProjectPartPchCompilerArguments(
+ const V2::ProjectPartContainer &projectPart) const
+{
+ Utils::SmallStringVector arguments;
+ arguments.reserve(5);
+
+ arguments.emplace_back("-x");
+ arguments.emplace_back("c++-header");
+// arguments.emplace_back("-Xclang");
+// arguments.emplace_back("-include-pch");
+// arguments.emplace_back("-Xclang");
+// arguments.emplace_back(generateGlobalPchFilePath());
+ arguments.emplace_back("-Xclang");
+ arguments.emplace_back("-emit-pch");
+ arguments.emplace_back("-o");
+ arguments.emplace_back(generateProjectPartPchFilePath(projectPart));
+ arguments.emplace_back(generateProjectPathPchHeaderFilePath(projectPart));
+
+ return arguments;
+}
+
+Utils::SmallStringVector PchCreator::generateProjectPartClangCompilerArguments(
+ const V2::ProjectPartContainer &projectPart) const
+{
+ Utils::SmallStringVector compilerArguments = projectPart.arguments().clone();
+ const auto pchArguments = generateProjectPartPchCompilerArguments(projectPart);
+
+ append(compilerArguments, pchArguments);
+
+ return compilerArguments;
+}
+
+std::pair<ProjectPartPch, IdPaths> PchCreator::generateProjectPartPch(
+ const V2::ProjectPartContainer &projectPart)
+{
+ auto includes = generateProjectPartPchIncludes(projectPart);
+ auto content = generatePchIncludeFileContent(includes);
+ auto pchIncludeFilePath = generateProjectPathPchHeaderFilePath(projectPart);
+ auto pchFilePath = generateProjectPartPchFilePath(projectPart);
+ auto file = generatePchHeaderFile(pchIncludeFilePath, content);
+
+ generatePch(generateProjectPartClangCompilerArguments(projectPart));
+
+ return {{projectPart.projectPartId().clone(), std::move(pchFilePath)},
+ {projectPart.projectPartId().clone(), includes}};
+}
+
+void PchCreator::generatePchs()
+{
+ for (const V2::ProjectPartContainer &projectPart : m_projectParts) {
+ auto projectInfos = generateProjectPartPch(projectPart);
+ m_projectPartPchs.push_back(projectInfos.first);
+ m_projectsIncludeIds.push_back(projectInfos.second);
+ }
+}
+
+void PchCreator::generatePchs(V2::ProjectPartContainers &&projectsParts)
+{
+ m_projectParts = std::move(projectsParts);
+
+ generatePchs();
+}
+
+std::vector<ProjectPartPch> PchCreator::takeProjectPartPchs()
+{
+ return std::move(m_projectPartPchs);
+}
+
+std::vector<IdPaths> PchCreator::takeProjectsIncludes()
+{
+ return std::move(m_projectsIncludeIds);
+}
+
+std::unique_ptr<QFile> PchCreator::generatePchHeaderFile(
+ const Utils::SmallString &filePath,
+ const Utils::SmallString &content)
+{
+ std::unique_ptr<QFile> precompiledIncludeFile(new QFile(filePath));
+
+ precompiledIncludeFile->open(QIODevice::WriteOnly);
+
+ precompiledIncludeFile->write(content.data(), content.size());
+ precompiledIncludeFile->close();
+
+ return precompiledIncludeFile;
+}
+
+QByteArray PchCreator::projectPartHash(const V2::ProjectPartContainer &projectPart)
+{
+ QCryptographicHash hash(QCryptographicHash::Sha1);
+
+ hashProjectPart(hash, projectPart);
+
+ auto result = hash.result();
+
+ return result.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h
new file mode 100644
index 0000000000..5bc38cb58b
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** 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
+
+#include "pchcreatorinterface.h"
+
+#include "stringcache.h"
+#include "idpaths.h"
+
+#include <projectpartpch.h>
+#include <projectpartcontainerv2.h>
+
+#include <vector>
+
+QT_FORWARD_DECLARE_CLASS(QFile)
+QT_FORWARD_DECLARE_CLASS(QCryptographicHash)
+QT_FORWARD_DECLARE_CLASS(QProcess)
+
+namespace ClangBackEnd {
+
+class Environment;
+
+class PchCreator final : public PchCreatorInterface
+{
+public:
+ PchCreator(Environment &environment,
+ StringCache<Utils::SmallString> &filePathCache);
+ PchCreator(V2::ProjectPartContainers &&projectsParts,
+ Environment &environment,
+ StringCache<Utils::SmallString> &filePathCache);
+
+ void generatePchs(V2::ProjectPartContainers &&projectsParts) override;
+ std::vector<ProjectPartPch> takeProjectPartPchs() override;
+ std::vector<IdPaths> takeProjectsIncludes() override;
+
+unitttest_public:
+ Utils::SmallStringVector generateGlobalHeaderPaths() const;
+ Utils::SmallStringVector generateGlobalSourcePaths() const;
+ Utils::SmallStringVector generateGlobalHeaderAndSourcePaths() const;
+ Utils::SmallStringVector generateGlobalArguments() const;
+ Utils::SmallStringVector generateGlobalCommandLine() const;
+ Utils::SmallStringVector generateGlobalPchCompilerArguments() const;
+ Utils::SmallStringVector generateGlobalClangCompilerArguments() const;
+
+ std::vector<uint> generateGlobalPchIncludeIds() const;
+
+ Utils::SmallString generatePchIncludeFileContent(const std::vector<uint> &includeIds) const;
+ Utils::SmallString generateGlobalPchHeaderFileContent() const;
+ std::unique_ptr<QFile> generateGlobalPchHeaderFile();
+ void generatePch(const Utils::SmallStringVector &commandLineArguments);
+ void generateGlobalPch();
+
+ Utils::SmallString globalPchContent() const;
+
+ static QStringList convertToQStringList(const Utils::SmallStringVector &convertToQStringList);
+
+ Utils::SmallString generateGlobalPchFilePathWithoutExtension() const;
+ Utils::SmallString generateGlobalPchHeaderFilePath() const;
+ Utils::SmallString generateGlobalPchFilePath() const;
+
+ Utils::SmallStringVector generateProjectPartCommandLine(
+ const V2::ProjectPartContainer &projectPart) const;
+ Utils::SmallString generateProjectPartPchFilePathWithoutExtension(
+ const V2::ProjectPartContainer &projectPart) const;
+ static Utils::SmallStringVector generateProjectPartHeaderAndSourcePaths(
+ const V2::ProjectPartContainer &projectPart);
+ std::vector<uint> generateProjectPartPchIncludes(
+ const V2::ProjectPartContainer &projectPart) const;
+ Utils::SmallString generateProjectPathPchHeaderFilePath(
+ const V2::ProjectPartContainer &projectPart) const;
+ Utils::SmallString generateProjectPartPchFilePath(
+ const V2::ProjectPartContainer &projectPart) const;
+ Utils::SmallStringVector generateProjectPartPchCompilerArguments(
+ const V2::ProjectPartContainer &projectPart) const;
+ Utils::SmallStringVector generateProjectPartClangCompilerArguments(
+ const V2::ProjectPartContainer &projectPart) const;
+ std::pair<ProjectPartPch, IdPaths> generateProjectPartPch(
+ const V2::ProjectPartContainer &projectPart);
+ static std::unique_ptr<QFile> generatePchHeaderFile(
+ const Utils::SmallString &filePath,
+ const Utils::SmallString &content);
+
+ void generatePchs();
+
+private:
+ static QByteArray projectPartHash(const V2::ProjectPartContainer &projectPart);
+ QByteArray globalProjectHash() const;
+ static void checkIfProcessHasError(const QProcess &process);
+
+private:
+ V2::ProjectPartContainers m_projectParts;
+ std::vector<ProjectPartPch> m_projectPartPchs;
+ std::vector<IdPaths> m_projectsIncludeIds;
+ Environment &m_environment;
+ StringCache<Utils::SmallString> &m_filePathCache;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.cpp b/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.cpp
new file mode 100644
index 0000000000..44d28dee01
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.cpp
@@ -0,0 +1,35 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "pchcreatorinterface.h"
+
+namespace ClangBackEnd {
+
+PchCreatorInterface::~PchCreatorInterface()
+{
+
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h b/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h
new file mode 100644
index 0000000000..89aac39bd5
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** 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
+
+#include "idpaths.h"
+#include "projectpartpch.h"
+
+#include <projectpartcontainerv2.h>
+
+namespace ClangBackEnd {
+
+class PchCreatorInterface
+{
+public:
+ virtual ~PchCreatorInterface();
+
+ virtual void generatePchs(V2::ProjectPartContainers &&projectsParts) = 0;
+ virtual std::vector<ProjectPartPch> takeProjectPartPchs() = 0;
+ virtual std::vector<IdPaths> takeProjectsIncludes() = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
new file mode 100644
index 0000000000..71ec82e45c
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "pchmanagerserver.h"
+
+#include <pchmanagerclientinterface.h>
+#include <precompiledheadersupdatedmessage.h>
+#include <removepchprojectpartsmessage.h>
+#include <updatepchprojectpartsmessage.h>
+
+#include <utils/smallstring.h>
+
+#include <QApplication>
+
+namespace ClangBackEnd {
+
+PchManagerServer::PchManagerServer(StringCache<Utils::SmallString> &filePathCache,
+ ClangPathWatcherInterface &fileSystemWatcher,
+ PchCreatorInterface &pchCreator,
+ ProjectPartsInterface &projectParts)
+ : m_filePathCache(filePathCache),
+ m_fileSystemWatcher(fileSystemWatcher),
+ m_pchCreator(pchCreator),
+ m_projectParts(projectParts)
+{
+ m_fileSystemWatcher.setNotifier(this);
+}
+
+void PchManagerServer::end()
+{
+ QCoreApplication::exit();
+
+}
+
+void PchManagerServer::updatePchProjectParts(UpdatePchProjectPartsMessage &&message)
+{
+ m_pchCreator.generatePchs(m_projectParts.update(message.takeProjectsParts()));
+
+ client()->precompiledHeadersUpdated(PrecompiledHeadersUpdatedMessage(m_pchCreator.takeProjectPartPchs()));
+
+ m_fileSystemWatcher.updateIdPaths(m_pchCreator.takeProjectsIncludes());
+}
+
+void PchManagerServer::removePchProjectParts(RemovePchProjectPartsMessage &&message)
+{
+ m_fileSystemWatcher.removeIds(message.projectsPartIds());
+
+ m_projectParts.remove(message.projectsPartIds());
+}
+
+void PchManagerServer::pathsWithIdsChanged(const Utils::SmallStringVector &ids)
+{
+ m_pchCreator.generatePchs(m_projectParts.projects(ids));
+
+ client()->precompiledHeadersUpdated(PrecompiledHeadersUpdatedMessage(m_pchCreator.takeProjectPartPchs()));
+
+ m_fileSystemWatcher.updateIdPaths(m_pchCreator.takeProjectsIncludes());
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
new file mode 100644
index 0000000000..b12ffeca7f
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** 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
+
+#include "clangpathwatcherinterface.h"
+#include "clangpathwatchernotifier.h"
+#include "pchcreatorinterface.h"
+#include "pchmanagerserverinterface.h"
+#include "projectpartsinterface.h"
+#include "stringcache.h"
+
+namespace ClangBackEnd {
+
+class SourceRangesAndDiagnosticsForQueryMessage;
+
+class PchManagerServer : public PchManagerServerInterface, public ClangPathWatcherNotifier
+{
+public:
+ PchManagerServer(StringCache<Utils::SmallString> &filePathCache,
+ ClangPathWatcherInterface &fileSystemWatcher,
+ PchCreatorInterface &pchCreator,
+ ProjectPartsInterface &projectParts);
+
+
+ void end() override;
+ void updatePchProjectParts(UpdatePchProjectPartsMessage &&message) override;
+ void removePchProjectParts(RemovePchProjectPartsMessage &&message) override;
+
+ void pathsWithIdsChanged(const Utils::SmallStringVector &ids) override;
+
+private:
+ StringCache<Utils::SmallString> &m_filePathCache;
+ ClangPathWatcherInterface &m_fileSystemWatcher;
+ PchCreatorInterface &m_pchCreator;
+ ProjectPartsInterface &m_projectParts;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchnotcreatederror.h b/src/tools/clangpchmanagerbackend/source/pchnotcreatederror.h
new file mode 100644
index 0000000000..6be51c0baa
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/pchnotcreatederror.h
@@ -0,0 +1,36 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+
+#include <stdexcept>
+
+namespace ClangBackEnd {
+
+class PchNotCreatedError : public std::runtime_error
+{
+ using std::runtime_error::runtime_error;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/projectparts.cpp b/src/tools/clangpchmanagerbackend/source/projectparts.cpp
new file mode 100644
index 0000000000..c79882766d
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/projectparts.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "projectparts.h"
+
+#include <projectpartcontainerv2.h>
+
+#include <algorithm>
+
+namespace ClangBackEnd {
+
+inline namespace Pch {
+
+V2::ProjectPartContainers ProjectParts::update(V2::ProjectPartContainers &&projectsParts)
+{
+ auto uniqueProjectParts = ProjectParts::uniqueProjectParts(std::move(projectsParts));
+
+ auto updatedProjectPartContainers = newProjectParts(std::move(uniqueProjectParts));
+
+ mergeProjectParts(updatedProjectPartContainers);
+
+ return updatedProjectPartContainers;
+}
+
+void ProjectParts::remove(const Utils::SmallStringVector &ids)
+{
+ auto shouldRemove = [&] (const V2::ProjectPartContainer &projectPart) {
+ return std::find(ids.begin(), ids.end(), projectPart.projectPartId()) != ids.end();
+ };
+
+ auto newEnd = std::remove_if(m_projectParts.begin(), m_projectParts.end(), shouldRemove);
+ m_projectParts.erase(newEnd, m_projectParts.end());
+}
+
+V2::ProjectPartContainers ProjectParts::projects(const Utils::SmallStringVector &projectPartIds) const
+{
+ V2::ProjectPartContainers projectPartsWithIds;
+
+ std::copy_if(m_projectParts.begin(),
+ m_projectParts.end(),
+ std::back_inserter(projectPartsWithIds),
+ [&] (const V2::ProjectPartContainer &projectPart) {
+ return std::binary_search(projectPartIds.begin(), projectPartIds.end(), projectPart.projectPartId());
+ });
+
+ return projectPartsWithIds;
+}
+
+V2::ProjectPartContainers ProjectParts::uniqueProjectParts(V2::ProjectPartContainers &&projectsParts)
+{
+ std::sort(projectsParts.begin(), projectsParts.end());
+ auto newEnd = std::unique(projectsParts.begin(), projectsParts.end());
+
+ projectsParts.erase(newEnd, projectsParts.end());
+
+ return std::move(projectsParts);
+}
+
+V2::ProjectPartContainers ProjectParts::newProjectParts(V2::ProjectPartContainers &&projectsParts) const
+{
+ V2::ProjectPartContainers updatedProjectPartContainers;
+ updatedProjectPartContainers.reserve(projectsParts.size());
+
+ std::set_difference(std::make_move_iterator(projectsParts.begin()),
+ std::make_move_iterator(projectsParts.end()),
+ m_projectParts.begin(),
+ m_projectParts.end(),
+ std::back_inserter(updatedProjectPartContainers));
+
+ return updatedProjectPartContainers;
+}
+
+void ProjectParts::mergeProjectParts(const V2::ProjectPartContainers &projectsParts)
+{
+ V2::ProjectPartContainers newProjectParts;
+ newProjectParts.reserve(m_projectParts.size() + projectsParts.size());
+
+ auto compare = [] (const V2::ProjectPartContainer &first, const V2::ProjectPartContainer &second) {
+ return first.projectPartId() < second.projectPartId();
+ };
+
+ std::set_union(projectsParts.begin(),
+ projectsParts.end(),
+ m_projectParts.begin(),
+ m_projectParts.end(),
+ std::back_inserter(newProjectParts),
+ compare);
+
+ m_projectParts = newProjectParts;
+}
+
+const V2::ProjectPartContainers &ProjectParts::projectParts() const
+{
+ return m_projectParts;
+}
+
+} // namespace Pch
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/projectparts.h b/src/tools/clangpchmanagerbackend/source/projectparts.h
new file mode 100644
index 0000000000..2651e22ce6
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/projectparts.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** 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
+
+#include "clangpchmanagerbackend_global.h"
+
+#include <projectpartsinterface.h>
+
+#include <utils/smallstringvector.h>
+
+namespace ClangBackEnd {
+
+inline namespace Pch {
+
+class ProjectParts final : public ProjectPartsInterface
+{
+public:
+ V2::ProjectPartContainers update(V2::ProjectPartContainers &&projectsParts) override;
+ void remove(const Utils::SmallStringVector &projectPartIds) override;
+ V2::ProjectPartContainers projects(const Utils::SmallStringVector &projectPartIds) const override;
+
+unitttest_public:
+ static V2::ProjectPartContainers uniqueProjectParts(V2::ProjectPartContainers &&projectsParts);
+ V2::ProjectPartContainers newProjectParts(V2::ProjectPartContainers &&projectsParts) const;
+ void mergeProjectParts(const V2::ProjectPartContainers &projectsParts);
+ const V2::ProjectPartContainers &projectParts() const;
+
+private:
+ V2::ProjectPartContainers m_projectParts;
+};
+
+} // namespace Pch
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartsinterface.cpp b/src/tools/clangpchmanagerbackend/source/projectpartsinterface.cpp
new file mode 100644
index 0000000000..fe7a0e6bd1
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/projectpartsinterface.cpp
@@ -0,0 +1,34 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "projectpartsinterface.h"
+
+namespace ClangBackEnd {
+
+ProjectPartsInterface::~ProjectPartsInterface()
+{
+}
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartsinterface.h b/src/tools/clangpchmanagerbackend/source/projectpartsinterface.h
new file mode 100644
index 0000000000..1c3ec785b3
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/projectpartsinterface.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** 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
+
+#include <projectpartcontainerv2.h>
+
+namespace ClangBackEnd {
+
+class ProjectPartsInterface
+{
+public:
+ virtual ~ProjectPartsInterface();
+
+ virtual V2::ProjectPartContainers update(V2::ProjectPartContainers &&projectsParts) = 0;
+ virtual void remove(const Utils::SmallStringVector &projectPartIds) = 0;
+ virtual V2::ProjectPartContainers projects(const Utils::SmallStringVector &projectPartIds) const = 0;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/stringcache.h b/src/tools/clangpchmanagerbackend/source/stringcache.h
new file mode 100644
index 0000000000..a85c314700
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/stringcache.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** 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
+
+#include "clangpchmanagerbackend_global.h"
+
+#include <utils/smallstringview.h>
+
+#include <algorithm>
+#include <vector>
+
+namespace ClangBackEnd {
+
+template <typename StringType>
+class StringCache
+{
+ class StringCacheEntry
+ {
+ public:
+ StringCacheEntry(StringType &&string, uint id)
+ : string(std::move(string)),
+ id(id)
+ {}
+
+ friend bool operator<(const StringCacheEntry &entry, Utils::SmallStringView stringView)
+ {
+ return entry.string < stringView;
+ }
+
+ friend bool operator<(Utils::SmallStringView stringView, const StringCacheEntry &entry)
+ {
+ return stringView < entry.string;
+ }
+
+ StringType string;
+ uint id;
+ };
+
+ using StringCacheEntries = std::vector<StringCacheEntry>;
+ using const_iterator = typename StringCacheEntries::const_iterator;
+
+ class Found
+ {
+ public:
+ typename StringCacheEntries::const_iterator iterator;
+ bool wasFound;
+ };
+
+
+public:
+ StringCache()
+ {
+ m_strings.reserve(1024);
+ m_indices.reserve(1024);
+ }
+
+ uint stringId(Utils::SmallStringView stringView)
+ {
+ Found found = find(stringView);
+
+ if (!found.wasFound)
+ return insertString(found.iterator, stringView);
+
+ return found.iterator->id;
+ }
+
+ std::vector<uint> stringIds(const std::vector<StringType> &strings)
+ {
+ std::vector<uint> ids;
+ ids.reserve(strings.size());
+
+ std::transform(strings.begin(),
+ strings.end(),
+ std::back_inserter(ids),
+ [&] (const StringType &string) { return stringId(string); });
+
+ return ids;
+ }
+
+ const StringType &string(uint id) const
+ {
+ return m_strings.at(m_indices.at(id)).string;
+ }
+
+ std::vector<StringType> strings(const std::vector<uint> &ids) const
+ {
+ std::vector<StringType> strings;
+ strings.reserve(ids.size());
+
+ std::transform(ids.begin(),
+ ids.end(),
+ std::back_inserter(strings),
+ [&] (uint id) { return m_strings.at(m_indices.at(id)).string; });
+
+ return strings;
+ }
+
+private:
+ Found find(Utils::SmallStringView stringView)
+ {
+ auto range = std::equal_range(m_strings.cbegin(), m_strings.cend(), stringView);
+
+ return {range.first, range.first != range.second};
+ }
+
+ void incrementLargerOrEqualIndicesByOne(uint newIndex)
+ {
+ std::transform(m_indices.begin(),
+ m_indices.end(),
+ m_indices.begin(),
+ [&] (uint index) {
+ return index >= newIndex ? ++index : index;
+ });
+ }
+
+ uint insertString(const_iterator beforeIterator,
+ Utils::SmallStringView stringView)
+ {
+ auto id = uint(m_strings.size());
+
+ auto inserted = m_strings.emplace(beforeIterator, StringType(stringView), id);
+
+ auto newIndex = uint(std::distance(m_strings.begin(), inserted));
+
+ incrementLargerOrEqualIndicesByOne(newIndex);
+
+ m_indices.push_back(newIndex);
+
+ return id;
+ }
+
+private:
+ StringCacheEntries m_strings;
+ std::vector<uint> m_indices;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/tools.pro b/src/tools/tools.pro
index 25506b7282..dc42b053bd 100644
--- a/src/tools/tools.pro
+++ b/src/tools/tools.pro
@@ -26,8 +26,9 @@ exists($$LLVM_INSTALL_DIR) {
win32-msvc2015:lessThan(QT_CL_PATCH_VERSION, 24210): QTC_NO_CLANG_LIBTOOLING = 1
isEmpty(QTC_NO_CLANG_LIBTOOLING) {
SUBDIRS += clangrefactoringbackend
+ SUBDIRS += clangpchmanagerbackend
} else {
- warning("Building the Clang refactoring back end is disabled.")
+ warning("Building the Clang refactoring back end and the pch manager plugins are disabled.")
}
}
diff --git a/tests/unit/unittest/clang_dependency.pri b/tests/unit/unittest/clang_dependency.pri
index 2a616fad49..c4cc608a9b 100644
--- a/tests/unit/unittest/clang_dependency.pri
+++ b/tests/unit/unittest/clang_dependency.pri
@@ -20,3 +20,5 @@ win32 {
LIBS += $$LIBTOOLING_LIBS $$LIBCLANG_LIBS
QMAKE_RPATHDIR += $$LLVM_LIBDIR
}
+
+DEFINES += CLANG_COMPILER_PATH=\"R\\\"xxx($$LLVM_INSTALL_DIR/bin/clang)xxx\\\"\"
diff --git a/tests/unit/unittest/clangpathwatcher-test.cpp b/tests/unit/unittest/clangpathwatcher-test.cpp
new file mode 100644
index 0000000000..04fd2bf912
--- /dev/null
+++ b/tests/unit/unittest/clangpathwatcher-test.cpp
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include "mockqfilesystemwatcher.h"
+#include "mockclangpathwatchernotifier.h"
+
+#include <clangpathwatcher.h>
+#include <stringcache.h>
+
+namespace {
+
+using testing::_;
+using testing::ElementsAre;
+using testing::IsEmpty;
+using testing::SizeIs;
+using testing::NiceMock;
+
+using Watcher = ClangBackEnd::ClangPathWatcher<NiceMock<MockQFileSytemWatcher>>;
+using ClangBackEnd::WatcherEntry;
+
+class ClangPathWatcher : public testing::Test
+{
+protected:
+ ClangBackEnd::StringCache<Utils::SmallString> pathCache;
+ NiceMock<MockClangPathWatcherNotifier> notifier;
+ Watcher watcher{pathCache, &notifier};
+ NiceMock<MockQFileSytemWatcher> &mockQFileSytemWatcher = watcher.fileSystemWatcher();
+ Utils::SmallString id1{"id4"};
+ Utils::SmallString id2{"id2"};
+ Utils::SmallString id3{"id3"};
+ Utils::SmallString path1{"/path/path1"};
+ Utils::SmallString path2{"/path/path2"};
+ std::vector<uint> paths = watcher.pathCache().stringIds({path1, path2});
+ std::vector<uint> ids = watcher.idCache().stringIds({id1, id2, id3});
+ WatcherEntry watcherEntry1{ids[0], paths[0]};
+ WatcherEntry watcherEntry2{ids[1], paths[0]};
+ WatcherEntry watcherEntry3{ids[0], paths[1]};
+ WatcherEntry watcherEntry4{ids[1], paths[1]};
+ WatcherEntry watcherEntry5{ids[2], paths[1]};
+};
+
+TEST_F(ClangPathWatcher, ConvertWatcherEntriesToQStringList)
+{
+ auto convertedList = watcher.convertWatcherEntriesToQStringList({watcherEntry1, watcherEntry3});
+
+ ASSERT_THAT(convertedList, ElementsAre(path1, path2));
+}
+
+TEST_F(ClangPathWatcher, UniquePaths)
+{
+ auto uniqueEntries = watcher.uniquePaths({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4});
+
+ ASSERT_THAT(uniqueEntries, ElementsAre(watcherEntry1, watcherEntry3));
+}
+
+TEST_F(ClangPathWatcher, NotWatchedEntries)
+{
+ watcher.addEntries({watcherEntry1, watcherEntry4});
+
+ auto newEntries = watcher.notWatchedEntries({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4});
+
+ ASSERT_THAT(newEntries, ElementsAre(watcherEntry2, watcherEntry3));
+}
+
+TEST_F(ClangPathWatcher, AddIdPaths)
+{
+ EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1, path2}));
+
+ watcher.updateIdPaths({{id1, {paths[0], paths[1]}}, {id2, {paths[0], paths[1]}}});
+}
+
+TEST_F(ClangPathWatcher, UpdateIdPathsCallsAddPathInFileWatcher)
+{
+ watcher.updateIdPaths({{id1, {paths[0]}}, {id2, {paths[0]}}});
+
+ EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path2}));
+
+ watcher.updateIdPaths({{id1, {paths[0], paths[1]}}, {id2, {paths[0], paths[1]}}});
+}
+
+TEST_F(ClangPathWatcher, UpdateIdPathsAndRemoveUnusedPathsCallsRemovePathInFileWatcher)
+{
+ watcher.updateIdPaths({{id1, {paths[0], paths[1]}}, {id2, {paths[0], paths[1]}}, {id3, {paths[0]}}});
+
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path2}));
+
+ watcher.updateIdPaths({{id1, {paths[0]}}, {id2, {paths[0]}}});
+}
+
+TEST_F(ClangPathWatcher, UpdateIdPathsAndRemoveUnusedPathsDoNotCallsRemovePathInFileWatcher)
+{
+ watcher.updateIdPaths({{id1, {paths[0], paths[1]}}, {id2, {paths[0], paths[1]}}, {id3, {paths[0]}}});
+
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path2}))
+ .Times(0);
+
+ watcher.updateIdPaths({{id1, {paths[1]}}, {id2, {paths[0]}}});
+}
+
+TEST_F(ClangPathWatcher, UpdateIdPathsAndRemoveUnusedPaths)
+{
+ watcher.updateIdPaths({{id1, {paths[0], paths[1]}}, {id2, {paths[0], paths[1]}}, {id3, {paths[1]}}});
+
+ watcher.updateIdPaths({{id1, {paths[0]}}, {id2, {paths[1]}}});
+
+ ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry1, watcherEntry4, watcherEntry5));
+}
+
+TEST_F(ClangPathWatcher, ExtractSortedEntriesFromConvertIdPaths)
+{
+ auto entriesAndIds = watcher.convertIdPathsToWatcherEntriesAndIds({{id2, {paths[0], paths[1]}}, {id1, {paths[0], paths[1]}}});
+
+ ASSERT_THAT(entriesAndIds.first, ElementsAre(watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4));
+}
+
+TEST_F(ClangPathWatcher, ExtractSortedIdsFromConvertIdPaths)
+{
+ auto entriesAndIds = watcher.convertIdPathsToWatcherEntriesAndIds({{id2, {}}, {id1, {}}, {id3, {}}});
+
+ ASSERT_THAT(entriesAndIds.second, ElementsAre(ids[0], ids[1], ids[2]));
+}
+
+TEST_F(ClangPathWatcher, NotWatchedPaths)
+{
+ watcher.mergeToWatchedEntries({watcherEntry1});
+
+ auto newEntries = watcher.notWatchedPaths({watcherEntry2, watcherEntry3});
+
+ ASSERT_THAT(newEntries, ElementsAre(watcherEntry3));
+}
+
+TEST_F(ClangPathWatcher, AddedPaths)
+{
+ watcher.mergeToWatchedEntries({watcherEntry1, watcherEntry2});
+
+ auto filteredEntries = watcher.filterNotWatchedPaths({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4});
+
+ ASSERT_THAT(filteredEntries, ElementsAre(watcherEntry3));
+}
+
+TEST_F(ClangPathWatcher, MergeEntries)
+{
+ watcher.mergeToWatchedEntries({watcherEntry1, watcherEntry4});
+
+ ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry1, watcherEntry4));
+}
+
+TEST_F(ClangPathWatcher, MergeMoreEntries)
+{
+ watcher.mergeToWatchedEntries({watcherEntry1, watcherEntry4});
+
+ watcher.mergeToWatchedEntries({watcherEntry2, watcherEntry3});
+
+ ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4));
+}
+
+TEST_F(ClangPathWatcher, AddEmptyEntries)
+{
+ EXPECT_CALL(mockQFileSytemWatcher, addPaths(_))
+ .Times(0);
+
+ watcher.addEntries({});
+}
+
+TEST_F(ClangPathWatcher, AddEntriesWithSameIdAndDifferentPaths)
+{
+ EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1, path2}));
+
+ watcher.addEntries({watcherEntry1, watcherEntry3});
+}
+
+TEST_F(ClangPathWatcher, AddEntriesWithDifferentIdAndSamePaths)
+{
+ EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1}));
+
+ watcher.addEntries({watcherEntry1, watcherEntry2});
+}
+
+TEST_F(ClangPathWatcher, DontAddNewEntriesWithSameIdAndSamePaths)
+{
+ watcher.addEntries({watcherEntry1});
+
+ EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1}))
+ .Times(0);
+
+ watcher.addEntries({watcherEntry1});
+}
+
+TEST_F(ClangPathWatcher, DontAddNewEntriesWithDifferentIdAndSamePaths)
+{
+ watcher.addEntries({watcherEntry1});
+
+ EXPECT_CALL(mockQFileSytemWatcher, addPaths(QStringList{path1}))
+ .Times(0);
+
+ watcher.addEntries({watcherEntry2});
+}
+
+TEST_F(ClangPathWatcher, RemoveEntriesWithId)
+{
+ watcher.addEntries({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5});
+
+ watcher.removeIdsFromWatchedEntries({ids[0]});
+
+ ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry2, watcherEntry4, watcherEntry5));
+}
+
+TEST_F(ClangPathWatcher, RemoveNoPathsForEmptyIds)
+{
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(_))
+ .Times(0);
+
+ watcher.removeIds({});
+}
+
+TEST_F(ClangPathWatcher, RemoveNoPathsForOneId)
+{
+ watcher.addEntries({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4});
+
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(_))
+ .Times(0);
+
+ watcher.removeIds({id1});
+}
+
+TEST_F(ClangPathWatcher, RemovePathForOneId)
+{
+ watcher.addEntries({watcherEntry1, watcherEntry2, watcherEntry3});
+
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path2}));
+
+ watcher.removeIds({id1});
+}
+
+TEST_F(ClangPathWatcher, RemoveAllPathsForThreeId)
+{
+ watcher.addEntries({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5});
+
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path1, path2}));
+
+ watcher.removeIds({id1, id2, id3});
+}
+
+TEST_F(ClangPathWatcher, RemoveOnePathForTwoId)
+{
+ watcher.addEntries({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5});
+
+ EXPECT_CALL(mockQFileSytemWatcher, removePaths(QStringList{path1}));
+
+ watcher.removeIds({id1, id2});
+}
+
+TEST_F(ClangPathWatcher, NotAnymoreWatchedEntriesWithId)
+{
+ watcher.addEntries({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5});
+
+ auto oldEntries = watcher.notAnymoreWatchedEntriesWithIds({watcherEntry1, watcherEntry4}, {ids[0], ids[1]});
+
+ ASSERT_THAT(oldEntries, ElementsAre(watcherEntry2, watcherEntry3));
+}
+
+TEST_F(ClangPathWatcher, RemoveUnusedEntries)
+{
+ watcher.addEntries({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5});
+
+ watcher.removeFromWatchedEntries({watcherEntry2, watcherEntry3});
+
+ ASSERT_THAT(watcher.watchedEntries(), ElementsAre(watcherEntry1, watcherEntry4, watcherEntry5));
+}
+
+TEST_F(ClangPathWatcher, EmptyVectorNotifyFileChange)
+{
+ watcher.addEntries({watcherEntry3});
+
+ EXPECT_CALL(notifier, pathsWithIdsChanged(IsEmpty())).Times(1);
+
+ mockQFileSytemWatcher.fileChanged(path1.toQString());
+}
+
+TEST_F(ClangPathWatcher, NotifyFileChange)
+{
+ watcher.addEntries({watcherEntry1, watcherEntry2, watcherEntry3, watcherEntry4, watcherEntry5});
+
+ EXPECT_CALL(notifier, pathsWithIdsChanged(ElementsAre(id2, id1)));
+
+ mockQFileSytemWatcher.fileChanged(path1.toQString());
+}
+
+}
diff --git a/tests/unit/unittest/creator_dependency.pri b/tests/unit/unittest/creator_dependency.pri
index c9a7c077c3..c39cb934d1 100644
--- a/tests/unit/unittest/creator_dependency.pri
+++ b/tests/unit/unittest/creator_dependency.pri
@@ -13,9 +13,11 @@ include($$PWD/../../../src/shared/clang/clang_defines.pri)
include($$PWD/../../../src/tools/clangbackend/ipcsource/clangbackendclangipc-source.pri)
!isEmpty(LIBTOOLING_LIBS):include($$PWD/../../../src/tools/clangrefactoringbackend/source/clangrefactoringbackend-source.pri)
+include($$PWD/../../../src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri)
include($$PWD/../../../src/plugins/clangcodemodel/clangcodemodelunittestfiles.pri)
include($$PWD/../../../src/plugins/cpptools/cpptoolsunittestfiles.pri)
!isEmpty(LIBTOOLING_LIBS):include($$PWD/../../../src/plugins/clangrefactoring/clangrefactoring-source.pri)
+include($$PWD/../../../src/plugins/clangpchmanager/clangpchmanager-source.pri)
include(cplusplus.pri)
}
diff --git a/tests/unit/unittest/data/includecollector_external1.h b/tests/unit/unittest/data/includecollector_external1.h
new file mode 100644
index 0000000000..8a406b0915
--- /dev/null
+++ b/tests/unit/unittest/data/includecollector_external1.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include <algorithm>
diff --git a/tests/unit/unittest/data/includecollector_external2.h b/tests/unit/unittest/data/includecollector_external2.h
new file mode 100644
index 0000000000..6f70f09bee
--- /dev/null
+++ b/tests/unit/unittest/data/includecollector_external2.h
@@ -0,0 +1 @@
+#pragma once
diff --git a/tests/unit/unittest/data/includecollector_external3.h b/tests/unit/unittest/data/includecollector_external3.h
new file mode 100644
index 0000000000..6f70f09bee
--- /dev/null
+++ b/tests/unit/unittest/data/includecollector_external3.h
@@ -0,0 +1 @@
+#pragma once
diff --git a/tests/unit/unittest/data/includecollector_header1.h b/tests/unit/unittest/data/includecollector_header1.h
new file mode 100644
index 0000000000..3f59c932d3
--- /dev/null
+++ b/tests/unit/unittest/data/includecollector_header1.h
@@ -0,0 +1,2 @@
+#pragma once
+
diff --git a/tests/unit/unittest/data/includecollector_header2.h b/tests/unit/unittest/data/includecollector_header2.h
new file mode 100644
index 0000000000..0a8989f116
--- /dev/null
+++ b/tests/unit/unittest/data/includecollector_header2.h
@@ -0,0 +1,3 @@
+#pragma once
+
+#include <includecollector_external3.h>
diff --git a/tests/unit/unittest/data/includecollector_main.cpp b/tests/unit/unittest/data/includecollector_main.cpp
new file mode 100644
index 0000000000..068bf9546b
--- /dev/null
+++ b/tests/unit/unittest/data/includecollector_main.cpp
@@ -0,0 +1,4 @@
+#include "includecollector_header1.h"
+#include "includecollector_header2.h"
+#include "includecollector_external1.h"
+#include "../data/includecollector_external2.h"
diff --git a/tests/unit/unittest/data/includecollector_main2.cpp b/tests/unit/unittest/data/includecollector_main2.cpp
new file mode 100644
index 0000000000..068bf9546b
--- /dev/null
+++ b/tests/unit/unittest/data/includecollector_main2.cpp
@@ -0,0 +1,4 @@
+#include "includecollector_header1.h"
+#include "includecollector_header2.h"
+#include "includecollector_external1.h"
+#include "../data/includecollector_external2.h"
diff --git a/tests/unit/unittest/data/includecollector_main3.cpp b/tests/unit/unittest/data/includecollector_main3.cpp
new file mode 100644
index 0000000000..9cfae8e577
--- /dev/null
+++ b/tests/unit/unittest/data/includecollector_main3.cpp
@@ -0,0 +1,4 @@
+#include <includecollector_header1.h>
+#include <includecollector_header2.h>
+#include <includecollector_external1.h>
+#include <includecollector_external2.h>
diff --git a/tests/unit/unittest/includecollector-test.cpp b/tests/unit/unittest/includecollector-test.cpp
new file mode 100644
index 0000000000..16e07a6e3b
--- /dev/null
+++ b/tests/unit/unittest/includecollector-test.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <includecollector.h>
+#include <stringcache.h>
+
+using testing::AllOf;
+using testing::Contains;
+using testing::Not;
+using testing::ElementsAre;
+using testing::UnorderedElementsAre;
+
+namespace {
+
+class IncludeCollector : public ::testing::Test
+{
+protected:
+ void SetUp();
+ uint id(const Utils::SmallString &path);
+
+protected:
+ ClangBackEnd::StringCache<Utils::SmallString> filePathCache;
+ ClangBackEnd::IncludeCollector collector{filePathCache};
+};
+
+TEST_F(IncludeCollector, IncludesExternalHeader)
+{
+ collector.collectIncludes();
+
+ ASSERT_THAT(collector.takeIncludeIds(),
+ AllOf(Contains(id("includecollector_external1.h")),
+ Contains(id("../data/includecollector_external2.h"))));
+}
+
+TEST_F(IncludeCollector, DoesNotIncludesInternalHeader)
+{
+ collector.collectIncludes();
+
+ ASSERT_THAT(collector.takeIncludeIds(), Not(Contains(id("includecollector_header1.h"))));
+}
+
+TEST_F(IncludeCollector, NoDuplicate)
+{
+ collector.collectIncludes();
+
+ ASSERT_THAT(collector.takeIncludeIds(),
+ UnorderedElementsAre(id("includecollector_external1.h"),
+ id("../data/includecollector_external2.h")));
+}
+
+TEST_F(IncludeCollector, IncludesAreSorted)
+{
+ collector.collectIncludes();
+
+ ASSERT_THAT(collector.takeIncludeIds(),
+ ElementsAre(id("includecollector_external1.h"),
+ id("../data/includecollector_external2.h")));
+}
+
+void IncludeCollector::SetUp()
+{
+ collector.addFile(TESTDATA_DIR, "includecollector_main.cpp", "", {"cc", "includecollector_main.cpp"});
+ collector.addFile(TESTDATA_DIR, "includecollector_main2.cpp", "", {"cc", "includecollector_main2.cpp"});
+
+ collector.setExcludedIncludes({TESTDATA_DIR "/includecollector_header1.h",
+ TESTDATA_DIR "/includecollector_header2.h"});
+}
+
+uint IncludeCollector::id(const Utils::SmallString &path)
+{
+ return filePathCache.stringId(path);
+}
+
+}
diff --git a/tests/unit/unittest/mockclangpathwatcher.h b/tests/unit/unittest/mockclangpathwatcher.h
new file mode 100644
index 0000000000..9539b1b652
--- /dev/null
+++ b/tests/unit/unittest/mockclangpathwatcher.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** 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
+
+#include "googletest.h"
+
+#include <clangpathwatcherinterface.h>
+
+class MockClangPathWatcher : public ClangBackEnd::ClangPathWatcherInterface
+{
+public:
+ MOCK_METHOD1(updateIdPaths,
+ void (const std::vector<ClangBackEnd::IdPaths> &idPaths));
+ MOCK_METHOD1(removeIds,
+ void (const Utils::SmallStringVector &ids));
+ MOCK_METHOD1(setNotifier,
+ void (ClangBackEnd::ClangPathWatcherNotifier *notifier));
+
+};
diff --git a/tests/unit/unittest/mockclangpathwatchernotifier.h b/tests/unit/unittest/mockclangpathwatchernotifier.h
new file mode 100644
index 0000000000..fa1b09972b
--- /dev/null
+++ b/tests/unit/unittest/mockclangpathwatchernotifier.h
@@ -0,0 +1,38 @@
+/****************************************************************************
+**
+** 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
+
+#include "googletest.h"
+
+#include <clangpathwatchernotifier.h>
+
+class MockClangPathWatcherNotifier : public ClangBackEnd::ClangPathWatcherNotifier
+{
+public:
+ MOCK_METHOD1(pathsWithIdsChanged,
+ void (const Utils::SmallStringVector &ids));
+};
+
diff --git a/tests/unit/unittest/mockpchcreator.h b/tests/unit/unittest/mockpchcreator.h
new file mode 100644
index 0000000000..d4cbd62793
--- /dev/null
+++ b/tests/unit/unittest/mockpchcreator.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** 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
+
+#include "googletest.h"
+
+#include <pchcreatorinterface.h>
+#include <projectpartpch.h>
+#include <projectpartcontainerv2.h>
+
+class MockPchCreator : public ClangBackEnd::PchCreatorInterface
+{
+public:
+ MOCK_METHOD1(generatePchs,
+ void(const std::vector<ClangBackEnd::V2::ProjectPartContainer> &projectParts));
+ MOCK_METHOD0(takeProjectPartPchs,
+ std::vector<ClangBackEnd::ProjectPartPch>());
+ MOCK_METHOD0(takeProjectsIncludes,
+ std::vector<ClangBackEnd::IdPaths>());
+
+ void generatePchs(std::vector<ClangBackEnd::V2::ProjectPartContainer> &&projectParts)
+ {
+ generatePchs(projectParts);
+ }
+};
diff --git a/tests/unit/unittest/mockpchmanagerclient.h b/tests/unit/unittest/mockpchmanagerclient.h
new file mode 100644
index 0000000000..f5d6632a60
--- /dev/null
+++ b/tests/unit/unittest/mockpchmanagerclient.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** 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
+
+#include "googletest.h"
+
+#include <pchmanagerclientinterface.h>
+
+class MockPchManagerClient : public ClangBackEnd::PchManagerClientInterface
+{
+public:
+ MOCK_METHOD0(alive,
+ void());
+ MOCK_METHOD1(precompiledHeadersUpdated,
+ void(const ClangBackEnd::PrecompiledHeadersUpdatedMessage &message));
+
+ void precompiledHeadersUpdated(ClangBackEnd::PrecompiledHeadersUpdatedMessage &&message) override
+ {
+ precompiledHeadersUpdated(message);
+ }
+};
diff --git a/tests/unit/unittest/mockpchmanagernotifier.h b/tests/unit/unittest/mockpchmanagernotifier.h
new file mode 100644
index 0000000000..961d383cae
--- /dev/null
+++ b/tests/unit/unittest/mockpchmanagernotifier.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** 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
+
+#include "googletest.h"
+
+#include <pchmanagernotifierinterface.h>
+
+class MockPchManagerNotifier : public ClangPchManager::PchManagerNotifierInterface
+{
+public:
+ MockPchManagerNotifier(ClangPchManager::PchManagerClient &pchManagerClient)
+ : ClangPchManager::PchManagerNotifierInterface(pchManagerClient)
+ {}
+
+ MOCK_METHOD2(precompiledHeaderUpdated,
+ void (const QString &projectPartId, const QString &pchFilePath));
+ MOCK_METHOD1(precompiledHeaderRemoved,
+ void (const QString &projectPartId));
+};
diff --git a/tests/unit/unittest/mockpchmanagerserver.h b/tests/unit/unittest/mockpchmanagerserver.h
new file mode 100644
index 0000000000..f5c703afd1
--- /dev/null
+++ b/tests/unit/unittest/mockpchmanagerserver.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** 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
+
+#include "googletest.h"
+
+#include <pchmanagerserverinterface.h>
+
+class MockPchManagerServer : public ClangBackEnd::PchManagerServerInterface
+{
+public:
+ MOCK_METHOD0(end,
+ void());
+ MOCK_METHOD1(updatePchProjectParts,
+ void (const ClangBackEnd::UpdatePchProjectPartsMessage&));
+ MOCK_METHOD1(removePchProjectParts,
+ void (const ClangBackEnd::RemovePchProjectPartsMessage&));
+
+ void updatePchProjectParts(ClangBackEnd::UpdatePchProjectPartsMessage &&message) override
+ {
+ updatePchProjectParts(message);
+ }
+
+ void removePchProjectParts(ClangBackEnd::RemovePchProjectPartsMessage &&message) override
+ {
+ removePchProjectParts(message);
+ }
+};
diff --git a/tests/unit/unittest/mockprojectparts.h b/tests/unit/unittest/mockprojectparts.h
new file mode 100644
index 0000000000..611e12b9fe
--- /dev/null
+++ b/tests/unit/unittest/mockprojectparts.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** 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
+
+#include "googletest.h"
+
+#include <projectpartsinterface.h>
+
+class MockProjectParts : public ClangBackEnd::ProjectPartsInterface
+{
+public:
+ MOCK_METHOD1(update,
+ ClangBackEnd::V2::ProjectPartContainers(const ClangBackEnd::V2::ProjectPartContainers &projectsParts));
+ MOCK_METHOD1(remove,
+ void(const Utils::SmallStringVector &projectPartIds));
+ MOCK_CONST_METHOD1(projects,
+ ClangBackEnd::V2::ProjectPartContainers(const Utils::SmallStringVector &projectPartIds));
+
+ ClangBackEnd::V2::ProjectPartContainers update(ClangBackEnd::V2::ProjectPartContainers &&projectsParts) override
+ {
+ return update(projectsParts);
+ }
+};
diff --git a/tests/unit/unittest/mockqfilesystemwatcher.h b/tests/unit/unittest/mockqfilesystemwatcher.h
new file mode 100644
index 0000000000..1bb90b2c37
--- /dev/null
+++ b/tests/unit/unittest/mockqfilesystemwatcher.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** 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
+
+#include "googletest.h"
+
+#include <QObject>
+
+class MockQFileSytemWatcher : public QObject
+{
+ Q_OBJECT
+
+public:
+ MOCK_METHOD1(addPaths,
+ void (const QStringList&));
+ MOCK_METHOD1(removePaths,
+ void (const QStringList&));
+
+signals:
+ void fileChanged(const QString &);
+};
diff --git a/tests/unit/unittest/mockrefactoringclient.h b/tests/unit/unittest/mockrefactoringclient.h
index 80db17eb96..3a0c653038 100644
--- a/tests/unit/unittest/mockrefactoringclient.h
+++ b/tests/unit/unittest/mockrefactoringclient.h
@@ -25,12 +25,9 @@
#pragma once
-#include <refactoringclientinterface.h>
+#include "googletest.h"
-#include <gmock/gmock.h>
-#include <gmock/gmock-matchers.h>
-#include <gtest/gtest.h>
-#include "gtest-qt-printing.h"
+#include <refactoringclientinterface.h>
class MockRefactoringClient : public ClangBackEnd::RefactoringClientInterface
{
diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp
new file mode 100644
index 0000000000..d57c2b7fe2
--- /dev/null
+++ b/tests/unit/unittest/pchcreator-test.cpp
@@ -0,0 +1,298 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include "testenvironment.h"
+
+#include <pchcreator.h>
+#include <stringcache.h>
+
+#include <QFileInfo>
+
+namespace {
+
+using ClangBackEnd::IdPaths;
+using ClangBackEnd::ProjectPartPch;
+using ClangBackEnd::V2::ProjectPartContainer;
+using Utils::SmallString;
+
+using testing::_;
+using testing::AllOf;
+using testing::Contains;
+using testing::ElementsAre;
+using testing::EndsWith;
+using testing::NiceMock;
+using testing::Not;
+using testing::UnorderedElementsAre;
+using testing::Property;
+using testing::Field;
+
+class PchCreator: public ::testing::Test
+{
+protected:
+ uint id(const Utils::SmallString &path);
+
+protected:
+ ClangBackEnd::StringCache<Utils::SmallString> filePathCache;
+ SmallString main1Path = TESTDATA_DIR "/includecollector_main3.cpp";
+ SmallString main2Path = TESTDATA_DIR "/includecollector_main2.cpp";
+ SmallString header1Path = TESTDATA_DIR "/includecollector_header1.h";
+ SmallString header2Path = TESTDATA_DIR "/includecollector_header2.h";
+ ProjectPartContainer projectPart1{"project1",
+ {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
+ {header1Path.clone()},
+ {main1Path.clone()}};
+ ProjectPartContainer projectPart2{"project2",
+ {"-I", TESTDATA_DIR, "-x", "c++-header", "-Wno-pragma-once-outside-header"},
+ {header2Path.clone()},
+ {main2Path.clone()}};
+ TestEnvironment environment;
+ ClangBackEnd::PchCreator creator{{projectPart1.clone(),projectPart2.clone()},
+ environment,
+ filePathCache};
+};
+
+using PchCreatorSlowTest = PchCreator;
+using PchCreatorVerySlowTest = PchCreator;
+
+TEST_F(PchCreator, CreateGlobalHeaderPaths)
+{
+ auto filePaths = creator.generateGlobalHeaderPaths();
+
+ ASSERT_THAT(filePaths,
+ UnorderedElementsAre(header1Path, header2Path));
+}
+
+TEST_F(PchCreator, CreateGlobalSourcePaths)
+{
+ auto filePaths = creator.generateGlobalSourcePaths();
+
+ ASSERT_THAT(filePaths,
+ UnorderedElementsAre(main1Path, main2Path));
+}
+
+TEST_F(PchCreator, CreateGlobalHeaderAndSourcePaths)
+{
+ auto filePaths = creator.generateGlobalHeaderAndSourcePaths();
+
+ ASSERT_THAT(filePaths,
+ UnorderedElementsAre(main1Path, main2Path, header1Path, header2Path));
+}
+
+TEST_F(PchCreator, CreateGlobalArguments)
+{
+ auto arguments = creator.generateGlobalArguments();
+
+ ASSERT_THAT(arguments, ElementsAre("-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header", "-I", TESTDATA_DIR, "-x" , "c++-header", "-Wno-pragma-once-outside-header"));
+}
+
+TEST_F(PchCreator, CreateGlobalCommandLine)
+{
+ auto arguments = creator.generateGlobalCommandLine();
+
+ ASSERT_THAT(arguments, ElementsAre(environment.clangCompilerPath(), "-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header", "-I", TESTDATA_DIR, "-x" , "c++-header", "-Wno-pragma-once-outside-header"));
+}
+
+TEST_F(PchCreator, CreateGlobalPchIncludes)
+{
+ auto includeIds = creator.generateGlobalPchIncludeIds();
+
+ ASSERT_THAT(includeIds,
+ UnorderedElementsAre(id("includecollector_external3.h"),
+ id("includecollector_external1.h"),
+ id("includecollector_external2.h")));
+}
+
+TEST_F(PchCreatorVerySlowTest, CreateGlobalPchFileContent)
+{
+ auto content = creator.generateGlobalPchHeaderFileContent();
+
+ ASSERT_THAT(content, "#include <includecollector_external3.h>\n#include <includecollector_external1.h>\n#include <includecollector_external2.h>\n");
+}
+
+TEST_F(PchCreatorVerySlowTest, CreateGlobalPchHeaderFile)
+{
+ auto file = creator.generateGlobalPchHeaderFile();
+ file->open(QIODevice::ReadOnly);
+
+ auto content = file->readAll();
+
+ ASSERT_THAT(content, "#include <includecollector_external3.h>\n#include <includecollector_external1.h>\n#include <includecollector_external2.h>\n");
+}
+
+TEST_F(PchCreator, ConvertToQStringList)
+{
+ auto arguments = creator.convertToQStringList({"-I", TESTDATA_DIR});
+
+ ASSERT_THAT(arguments, ElementsAre(QString("-I"), QString(TESTDATA_DIR)));
+}
+
+TEST_F(PchCreator, CreateGlobalPchCompilerArguments)
+{
+ auto arguments = creator.generateGlobalPchCompilerArguments();
+
+ ASSERT_THAT(arguments, ElementsAre("-x","c++-header", "-Xclang", "-emit-pch", "-o", EndsWith(".pch"), EndsWith(".h")));
+}
+
+TEST_F(PchCreator, CreateGlobalClangCompilerArguments)
+{
+ auto arguments = creator.generateGlobalClangCompilerArguments();
+
+ ASSERT_THAT(arguments, AllOf(Contains("-Wno-pragma-once-outside-header"),
+ Contains("-emit-pch"),
+ Contains("-o"),
+ Not(Contains(environment.clangCompilerPath()))));
+}
+
+TEST_F(PchCreatorVerySlowTest, CreateGlobalPch)
+{
+ creator.generateGlobalPch();
+
+ ASSERT_TRUE(QFileInfo::exists(creator.generateGlobalPchFilePath()));
+}
+
+TEST_F(PchCreator, CreateProjectPartCommandLine)
+{
+ auto commandLine = creator.generateProjectPartCommandLine(projectPart1);
+
+ ASSERT_THAT(commandLine, ElementsAre(environment.clangCompilerPath(), "-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"));
+}
+
+TEST_F(PchCreator, CreateProjectPartHeaderAndSources)
+{
+ auto includeIds = creator.generateProjectPartHeaderAndSourcePaths(projectPart1);
+
+ ASSERT_THAT(includeIds, UnorderedElementsAre(main1Path, header1Path));
+}
+
+TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludes)
+{
+ auto includeIds = creator.generateProjectPartPchIncludes(projectPart1);
+
+ ASSERT_THAT(includeIds, UnorderedElementsAre(id("includecollector_external1.h"),
+ id("includecollector_external2.h"),
+ id("includecollector_header2.h")));
+}
+
+TEST_F(PchCreatorSlowTest, CreateProjectPartPchFileContent)
+{
+ auto includes = creator.generateProjectPartPchIncludes(projectPart1);
+
+ auto content = creator.generatePchIncludeFileContent(includes);
+
+ ASSERT_THAT(content, "#include <includecollector_header2.h>\n#include <includecollector_external1.h>\n#include <includecollector_external2.h>\n");
+}
+
+TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludeFile)
+{
+ auto includeIds = creator.generateProjectPartPchIncludes(projectPart1);
+ auto content = creator.generatePchIncludeFileContent(includeIds);
+ auto pchIncludeFilePath = creator.generateProjectPathPchHeaderFilePath(projectPart1);
+ auto file = creator.generatePchHeaderFile(pchIncludeFilePath, content);
+ file->open(QIODevice::ReadOnly);
+
+ auto fileContent = file->readAll();
+
+ ASSERT_THAT(fileContent, "#include <includecollector_header2.h>\n#include <includecollector_external1.h>\n#include <includecollector_external2.h>\n");
+}
+
+TEST_F(PchCreator, CreateProjectPartPchCompilerArguments)
+{
+ auto arguments = creator.generateProjectPartPchCompilerArguments(projectPart1);
+
+ ASSERT_THAT(arguments, AllOf(Contains("-x"),
+ Contains("c++-header"),
+// Contains("-Xclang"),
+// Contains("-include-pch"),
+// Contains("-Xclang"),
+// Contains(EndsWith(".pch")),
+ Contains("-Xclang"),
+ Contains("-emit-pch"),
+ Contains("-o"),
+ Contains(EndsWith(".pch"))));
+}
+
+TEST_F(PchCreator, CreateProjectPartClangCompilerArguments)
+{
+ auto arguments = creator.generateProjectPartClangCompilerArguments(projectPart1);
+
+ ASSERT_THAT(arguments, AllOf(Contains(TESTDATA_DIR),
+ Contains("-emit-pch"),
+ Contains("-o"),
+ Not(Contains(environment.clangCompilerPath()))));
+}
+
+TEST_F(PchCreatorVerySlowTest, ProjectPartPchsExistsAfterCreation)
+{
+ creator.generateGlobalPch();
+
+ creator.generateProjectPartPch(projectPart1);
+
+ ASSERT_TRUE(QFileInfo::exists(creator.generateProjectPathPchHeaderFilePath(projectPart1)));
+}
+
+TEST_F(PchCreatorVerySlowTest, CreatePartPchs)
+{
+ creator.generateGlobalPch();
+
+ auto projectPartPchAndIdPath = creator.generateProjectPartPch(projectPart1);
+
+ ASSERT_THAT(projectPartPchAndIdPath.first.id(), projectPart1.projectPartId());
+ ASSERT_THAT(projectPartPchAndIdPath.first.path(), creator.generateProjectPartPchFilePath(projectPart1));
+ ASSERT_THAT(projectPartPchAndIdPath.second.id, projectPart1.projectPartId());
+ ASSERT_THAT(projectPartPchAndIdPath.second.paths, UnorderedElementsAre(1, 2, 3));
+}
+
+TEST_F(PchCreatorVerySlowTest, ProjectPartPchsForCreatePchsForProjectParts)
+{
+ creator.generatePchs();
+
+ ASSERT_THAT(creator.takeProjectPartPchs(),
+ ElementsAre(Property(&ProjectPartPch::id, "project1"),
+ Property(&ProjectPartPch::id, "project2")));
+}
+
+TEST_F(PchCreatorVerySlowTest, IdPathsForCreatePchsForProjectParts)
+{
+ creator.generatePchs();
+
+ ASSERT_THAT(creator.takeProjectsIncludes(),
+ ElementsAre(AllOf(Field(&IdPaths::id, "project1"),
+ Field(&IdPaths::paths, UnorderedElementsAre(id("includecollector_header2.h"),
+ id("includecollector_external1.h"),
+ id("includecollector_external2.h")))),
+ AllOf(Field(&IdPaths::id, "project2"),
+ Field(&IdPaths::paths, UnorderedElementsAre(id("includecollector_external1.h"),
+ id("includecollector_external3.h"),
+ id("includecollector_header1.h"),
+ id("../data/includecollector_external2.h"))))));
+}
+
+uint PchCreator::id(const Utils::SmallString &path)
+{
+ return filePathCache.stringId(path);
+}
+}
diff --git a/tests/unit/unittest/pchmanagerclient-test.cpp b/tests/unit/unittest/pchmanagerclient-test.cpp
new file mode 100644
index 0000000000..6e0ac27101
--- /dev/null
+++ b/tests/unit/unittest/pchmanagerclient-test.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include "mockpchmanagernotifier.h"
+#include "mockpchmanagerserver.h"
+
+#include <pchmanagerclient.h>
+#include <projectupdater.h>
+
+#include <precompiledheadersupdatedmessage.h>
+#include <removepchprojectpartsmessage.h>
+#include <updatepchprojectpartsmessage.h>
+
+namespace {
+
+using ClangBackEnd::PrecompiledHeadersUpdatedMessage;
+
+using testing::_;
+using testing::Contains;
+using testing::Not;
+
+class PchManagerClient : public ::testing::Test
+{
+protected:
+ MockPchManagerServer mockPchManagerServer;
+ ClangPchManager::PchManagerClient client;
+ MockPchManagerNotifier mockPchManagerNotifier{client};
+ ClangPchManager::ProjectUpdater projectUpdater{mockPchManagerServer, client};
+ Utils::SmallString projectPartId{"projectPartId"};
+ Utils::SmallString pchFilePath{"/path/to/pch"};
+ PrecompiledHeadersUpdatedMessage message{{{projectPartId.clone(), pchFilePath.clone()}}};
+};
+
+TEST_F(PchManagerClient, NotifierAttached)
+{
+ MockPchManagerNotifier notifier(client);
+
+ ASSERT_THAT(client.notifiers(), Contains(&notifier));
+}
+
+TEST_F(PchManagerClient, NotifierDetached)
+{
+ MockPchManagerNotifier *notifierPointer = nullptr;
+
+ {
+ MockPchManagerNotifier notifier(client);
+ notifierPointer = &notifier;
+ }
+
+ ASSERT_THAT(client.notifiers(), Not(Contains(notifierPointer)));
+}
+
+TEST_F(PchManagerClient, Update)
+{
+ EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderUpdated(projectPartId.toQString(), pchFilePath.toQString()));
+
+ client.precompiledHeadersUpdated(message.clone());
+}
+
+TEST_F(PchManagerClient, Remove)
+{
+ EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId.toQString()))
+ .Times(2);
+
+ projectUpdater.removeProjectParts({projectPartId.clone(), projectPartId.clone()});
+}
+
+}
diff --git a/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp
new file mode 100644
index 0000000000..6ae9ff8fa3
--- /dev/null
+++ b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include "mockpchmanagerclient.h"
+#include "mockpchmanagerserver.h"
+
+#include <writemessageblock.h>
+#include <pchmanagerclientproxy.h>
+#include <pchmanagerserverproxy.h>
+#include <precompiledheadersupdatedmessage.h>
+#include <removepchprojectpartsmessage.h>
+#include <updatepchprojectpartsmessage.h>
+
+#include <QBuffer>
+#include <QString>
+#include <QVariant>
+
+#include <vector>
+
+using ClangBackEnd::UpdatePchProjectPartsMessage;
+using ClangBackEnd::V2::ProjectPartContainer;
+using ClangBackEnd::RemovePchProjectPartsMessage;
+using ClangBackEnd::PrecompiledHeadersUpdatedMessage;
+
+using ::testing::Args;
+using ::testing::Property;
+using ::testing::Eq;
+
+namespace {
+
+class PchManagerClientServerInProcess : public ::testing::Test
+{
+protected:
+ PchManagerClientServerInProcess();
+
+ void SetUp();
+ void TearDown();
+
+ void scheduleServerMessages();
+ void scheduleClientMessages();
+
+protected:
+ QBuffer buffer;
+ MockPchManagerClient mockPchManagerClient;
+ MockPchManagerServer mockPchManagerServer;
+
+ ClangBackEnd::PchManagerServerProxy serverProxy;
+ ClangBackEnd::PchManagerClientProxy clientProxy;
+};
+
+TEST_F(PchManagerClientServerInProcess, SendEndMessage)
+{
+ EXPECT_CALL(mockPchManagerServer, end());
+
+ serverProxy.end();
+ scheduleServerMessages();
+}
+
+TEST_F(PchManagerClientServerInProcess, SendAliveMessage)
+{
+
+ EXPECT_CALL(mockPchManagerClient, alive());
+
+ clientProxy.alive();
+ scheduleClientMessages();
+}
+
+TEST_F(PchManagerClientServerInProcess, SendUpdatePchProjectPartsMessage)
+{
+ ProjectPartContainer projectPart2{"projectPartId",
+ {"-x", "c++-header", "-Wno-pragma-once-outside-header"},
+ {TESTDATA_DIR "/includecollector_header.h"},
+ {TESTDATA_DIR "/includecollector_main.cpp"}};
+ UpdatePchProjectPartsMessage message{{projectPart2}};
+
+ EXPECT_CALL(mockPchManagerServer, updatePchProjectParts(message));
+
+ serverProxy.updatePchProjectParts(message.clone());
+ scheduleServerMessages();
+}
+
+TEST_F(PchManagerClientServerInProcess, SendRemovePchProjectPartsMessage)
+{
+ RemovePchProjectPartsMessage message{{"projectPartId1", "projectPartId2"}};
+
+ EXPECT_CALL(mockPchManagerServer, removePchProjectParts(message));
+
+ serverProxy.removePchProjectParts(message.clone());
+ scheduleServerMessages();
+}
+
+TEST_F(PchManagerClientServerInProcess, SendPrecompiledHeaderUpdatedMessage)
+{
+ PrecompiledHeadersUpdatedMessage message{{{"projectPartId", "/path/to/pch"}}};
+
+
+ EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(message));
+
+ clientProxy.precompiledHeadersUpdated(message.clone());
+ scheduleClientMessages();
+}
+
+PchManagerClientServerInProcess::PchManagerClientServerInProcess()
+ : serverProxy(&mockPchManagerClient, &buffer),
+ clientProxy(&mockPchManagerServer, &buffer)
+{
+}
+
+void PchManagerClientServerInProcess::SetUp()
+{
+ buffer.open(QIODevice::ReadWrite);
+}
+
+void PchManagerClientServerInProcess::TearDown()
+{
+ buffer.close();
+}
+
+void PchManagerClientServerInProcess::scheduleServerMessages()
+{
+ buffer.seek(0);
+ clientProxy.readMessages();
+ buffer.buffer().clear();
+}
+
+void PchManagerClientServerInProcess::scheduleClientMessages()
+{
+ buffer.seek(0);
+ serverProxy.readMessages();
+ buffer.buffer().clear();
+}
+
+}
diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp
new file mode 100644
index 0000000000..7c174794c0
--- /dev/null
+++ b/tests/unit/unittest/pchmanagerserver-test.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include "mockclangpathwatcher.h"
+#include "mockpchmanagerclient.h"
+#include "mockpchcreator.h"
+#include "mockprojectparts.h"
+
+#include <pchmanagerserver.h>
+#include <precompiledheadersupdatedmessage.h>
+#include <removepchprojectpartsmessage.h>
+#include <updatepchprojectpartsmessage.h>
+
+namespace {
+
+using testing::ElementsAre;
+using testing::UnorderedElementsAre;
+using testing::ByMove;
+using testing::NiceMock;
+using testing::Return;
+using testing::_;
+using testing::IsEmpty;
+
+using Utils::SmallString;
+using ClangBackEnd::V2::ProjectPartContainer;
+
+class PchManagerServer : public ::testing::Test
+{
+ void SetUp() override;
+
+protected:
+ NiceMock<MockPchCreator> mockPchCreator;
+ NiceMock<MockClangPathWatcher> mockClangPathWatcher;
+ NiceMock<MockProjectParts> mockProjectParts;
+ ClangBackEnd::StringCache<Utils::SmallString> filePathCache;
+ ClangBackEnd::PchManagerServer server{filePathCache, mockClangPathWatcher, mockPchCreator, mockProjectParts};
+ NiceMock<MockPchManagerClient> mockPchManagerClient;
+ SmallString projectPartId1 = "project1";
+ SmallString projectPartId2 = "project2";
+ SmallString main1Path = TESTDATA_DIR "/includecollector_main3.cpp";
+ SmallString main2Path = TESTDATA_DIR "/includecollector_main2.cpp";
+ SmallString header1Path = TESTDATA_DIR "/includecollector_header1.h";
+ SmallString header2Path = TESTDATA_DIR "/includecollector_header2.h";
+ std::vector<ClangBackEnd::IdPaths> idPaths = {{projectPartId1, {1, 2}}};
+ ProjectPartContainer projectPart1{projectPartId1.clone(),
+ {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
+ {header1Path.clone()},
+ {main1Path.clone()}};
+ ProjectPartContainer projectPart2{projectPartId2.clone(),
+ {"-x", "c++-header", "-Wno-pragma-once-outside-header"},
+ {header2Path.clone()},
+ {main2Path.clone()}};
+ std::vector<ClangBackEnd::V2::ProjectPartContainer> projectParts{projectPart1, projectPart2};
+ ClangBackEnd::UpdatePchProjectPartsMessage updatePchProjectPartsMessage{Utils::clone(projectParts)};
+ std::vector<ClangBackEnd::ProjectPartPch> projectPartPchs{{projectPart1.projectPartId().clone(), "/path1/to/pch"},
+ {projectPart2.projectPartId().clone(), "/path2/to/pch"}};
+ ClangBackEnd::PrecompiledHeadersUpdatedMessage precompiledHeaderUpdatedMessage{Utils::clone(projectPartPchs)};
+ ClangBackEnd::RemovePchProjectPartsMessage removePchProjectPartsMessage{{projectPart1.projectPartId().clone(),
+ projectPart2.projectPartId().clone()}};
+};
+
+TEST_F(PchManagerServer, CallPrecompiledHeadersUpdatedInClientForUpdate)
+{
+ EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(precompiledHeaderUpdatedMessage));
+
+ server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
+}
+
+TEST_F(PchManagerServer, CallBuildInPchCreator)
+{
+ EXPECT_CALL(mockPchCreator, generatePchs(updatePchProjectPartsMessage.projectsParts()));
+
+ server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
+}
+
+TEST_F(PchManagerServer, UpdateIncludesOfFileWatcher)
+{
+ EXPECT_CALL(mockClangPathWatcher, updateIdPaths(idPaths));
+
+ server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
+}
+
+TEST_F(PchManagerServer, GetChangedProjectPartsFromProjectParts)
+{
+ EXPECT_CALL(mockProjectParts, update(_));
+
+ server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
+}
+
+TEST_F(PchManagerServer, RemoveIncludesFromFileWatcher)
+{
+ EXPECT_CALL(mockClangPathWatcher, removeIds(removePchProjectPartsMessage.projectsPartIds()));
+
+ server.removePchProjectParts(removePchProjectPartsMessage.clone());
+}
+
+TEST_F(PchManagerServer, RemoveProjectPartsFromProjectParts)
+{
+ EXPECT_CALL(mockProjectParts, remove(removePchProjectPartsMessage.projectsPartIds()));
+
+ server.removePchProjectParts(removePchProjectPartsMessage.clone());
+}
+
+TEST_F(PchManagerServer, SetPathWatcherNotifier)
+{
+ EXPECT_CALL(mockClangPathWatcher, setNotifier(_));
+
+ ClangBackEnd::PchManagerServer server{filePathCache, mockClangPathWatcher, mockPchCreator, mockProjectParts};
+}
+
+TEST_F(PchManagerServer, CallProjectsInProjectPartsForIncludeChange)
+{
+ server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
+
+ EXPECT_CALL(mockProjectParts, projects(ElementsAre(projectPart1.projectPartId())));
+
+ server.pathsWithIdsChanged({projectPartId1});
+}
+
+TEST_F(PchManagerServer, CallGeneratePchsInPchCreatorForIncludeChange)
+{
+ server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
+
+ EXPECT_CALL(mockPchCreator, generatePchs(ElementsAre(projectPart1)));
+
+ server.pathsWithIdsChanged({projectPartId1});
+}
+
+TEST_F(PchManagerServer, CallPrecompiledHeadersUpdatedInClientForIncludeChange)
+{
+ server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
+
+ EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(precompiledHeaderUpdatedMessage));
+
+ server.pathsWithIdsChanged({projectPartId1});
+}
+
+TEST_F(PchManagerServer, CallUpdateIdPathsInFileSystemWatcherForIncludeChange)
+{
+ server.updatePchProjectParts(updatePchProjectPartsMessage.clone());
+
+ EXPECT_CALL(mockClangPathWatcher, updateIdPaths(idPaths));
+
+ server.pathsWithIdsChanged({projectPartId1});
+}
+
+void PchManagerServer::SetUp()
+{
+ server.setClient(&mockPchManagerClient);
+
+ ON_CALL(mockPchCreator, takeProjectPartPchs())
+ .WillByDefault(Return(projectPartPchs));
+ ON_CALL(mockProjectParts, update(projectParts))
+ .WillByDefault(Return(projectParts));
+ ON_CALL(mockProjectParts, projects(Utils::SmallStringVector{{projectPartId1}}))
+ .WillByDefault(Return(std::vector<ClangBackEnd::V2::ProjectPartContainer>{{projectPart1}}));
+ ON_CALL(mockPchCreator, takeProjectsIncludes())
+ .WillByDefault(Return(idPaths));
+}
+}
diff --git a/tests/unit/unittest/projectparts-test.cpp b/tests/unit/unittest/projectparts-test.cpp
new file mode 100644
index 0000000000..e8680dbccc
--- /dev/null
+++ b/tests/unit/unittest/projectparts-test.cpp
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <projectparts.h>
+
+#include <projectpartcontainerv2.h>
+
+namespace {
+
+using testing::ElementsAre;
+using testing::UnorderedElementsAre;
+using testing::IsEmpty;
+
+using ClangBackEnd::V2::ProjectPartContainer;
+
+class ProjectParts : public testing::Test
+{
+protected:
+ ClangBackEnd::ProjectParts projectParts;
+ ProjectPartContainer projectPartContainer1{"id",
+ {"-DUNIX", "-O2"},
+ {"headers1.h", "header2.h"},
+ {"source1.cpp", "source2.cpp"}};
+ ProjectPartContainer updatedProjectPartContainer1{"id",
+ {"-DUNIX", "-O2"},
+ {"headers1.h", "header2.h"},
+ {"source1.cpp", "source2.cpp", "source3.cpp" }};
+ ProjectPartContainer projectPartContainer2{"id2",
+ {"-DUNIX", "-O2"},
+ {"headers1.h", "header2.h"},
+ {"source1.cpp", "source2.cpp"}};
+};
+
+TEST_F(ProjectParts, GetNoProjectPartsForAddingEmptyProjectParts)
+{
+ auto updatedProjectParts = projectParts.update({});
+
+ ASSERT_THAT(updatedProjectParts, IsEmpty());
+}
+
+TEST_F(ProjectParts, GetProjectPartForAddingProjectPart)
+{
+ auto updatedProjectParts = projectParts.update({projectPartContainer1});
+
+ ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer1));
+}
+
+TEST_F(ProjectParts, ProjectPartAdded)
+{
+ projectParts.update({projectPartContainer1});
+
+ ASSERT_THAT(projectParts.projectParts(), ElementsAre(projectPartContainer1));
+}
+
+TEST_F(ProjectParts, FilterDublicateProjectPartsForUpdating)
+{
+ auto updatedProjectParts = projectParts.update({projectPartContainer1, projectPartContainer1});
+
+ ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer1));
+}
+
+TEST_F(ProjectParts, FilteredProjectPartAdded)
+{
+ projectParts.update({projectPartContainer1, projectPartContainer1});
+
+ ASSERT_THAT(projectParts.projectParts(), ElementsAre(projectPartContainer1));
+}
+
+TEST_F(ProjectParts, DoNotUpdateNotNewProjectPart)
+{
+ projectParts.update({projectPartContainer1});
+
+ auto updatedProjectParts = projectParts.update({projectPartContainer1});
+
+ ASSERT_THAT(updatedProjectParts, IsEmpty());
+}
+
+TEST_F(ProjectParts, NoDuplicateProjectPartAfterUpdatingWithNotNewProjectPart)
+{
+ projectParts.update({projectPartContainer1});
+
+ auto updatedProjectParts = projectParts.update({projectPartContainer1});
+
+ ASSERT_THAT(projectParts.projectParts(), ElementsAre(projectPartContainer1));
+}
+
+TEST_F(ProjectParts, FilterUniqueProjectParts)
+{
+ auto updatedProjectParts = projectParts.uniqueProjectParts({projectPartContainer1, projectPartContainer2, projectPartContainer1});
+
+ ASSERT_THAT(updatedProjectParts, ElementsAre(projectPartContainer1, projectPartContainer2));
+}
+
+TEST_F(ProjectParts, MergeProjectParts)
+{
+ projectParts.mergeProjectParts({projectPartContainer1, projectPartContainer2});
+
+ ASSERT_THAT(projectParts.projectParts(), ElementsAre(projectPartContainer1, projectPartContainer2));
+}
+
+TEST_F(ProjectParts, MergeProjectMultipleTimesParts)
+{
+ projectParts.mergeProjectParts({projectPartContainer2});
+
+ projectParts.mergeProjectParts({projectPartContainer1});
+
+ ASSERT_THAT(projectParts.projectParts(), ElementsAre(projectPartContainer1, projectPartContainer2));
+}
+
+TEST_F(ProjectParts, GetNewProjectParts)
+{
+ projectParts.mergeProjectParts({projectPartContainer2});
+
+ auto newProjectParts = projectParts.newProjectParts({projectPartContainer1, projectPartContainer2});
+
+ ASSERT_THAT(newProjectParts, ElementsAre(projectPartContainer1));
+}
+
+TEST_F(ProjectParts, GetUpdatedProjectPart)
+{
+ projectParts.update({projectPartContainer1, projectPartContainer2});
+
+ auto updatedProjectParts = projectParts.update({updatedProjectPartContainer1});
+
+ ASSERT_THAT(updatedProjectParts, ElementsAre(updatedProjectPartContainer1));
+}
+
+TEST_F(ProjectParts, ProjectPartIsReplacedWithUpdatedProjectPart)
+{
+ projectParts.update({projectPartContainer1, projectPartContainer2});
+
+ projectParts.update({updatedProjectPartContainer1});
+
+ ASSERT_THAT(projectParts.projectParts(), ElementsAre(updatedProjectPartContainer1, projectPartContainer2));
+}
+
+TEST_F(ProjectParts, Remove)
+{
+ projectParts.update({projectPartContainer1, projectPartContainer2});
+
+ projectParts.remove({projectPartContainer1.projectPartId()});
+
+ ASSERT_THAT(projectParts.projectParts(), ElementsAre(projectPartContainer2));
+}
+
+TEST_F(ProjectParts, GetProjectById)
+{
+ projectParts.update({projectPartContainer1, projectPartContainer2});
+
+ auto projectPartContainers = projectParts.projects({projectPartContainer1.projectPartId()});
+
+ ASSERT_THAT(projectPartContainers, ElementsAre(projectPartContainer1));
+}
+
+
+TEST_F(ProjectParts, GetProjectsByIds)
+{
+ projectParts.update({projectPartContainer1, projectPartContainer2});
+
+ auto projectPartContainers = projectParts.projects({projectPartContainer1.projectPartId(), projectPartContainer2.projectPartId()});
+
+ ASSERT_THAT(projectPartContainers, UnorderedElementsAre(projectPartContainer1, projectPartContainer2));
+}
+
+}
diff --git a/tests/unit/unittest/projectupdater-test.cpp b/tests/unit/unittest/projectupdater-test.cpp
new file mode 100644
index 0000000000..7a5e45e21a
--- /dev/null
+++ b/tests/unit/unittest/projectupdater-test.cpp
@@ -0,0 +1,140 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include "mockpchmanagerclient.h"
+#include "mockpchmanagernotifier.h"
+#include "mockpchmanagerserver.h"
+
+#include <projectupdater.h>
+
+#include <pchmanagerclient.h>
+#include <precompiledheadersupdatedmessage.h>
+#include <removepchprojectpartsmessage.h>
+#include <updatepchprojectpartsmessage.h>
+
+#include <cpptools/clangcompileroptionsbuilder.h>
+#include <cpptools/projectpart.h>
+
+namespace {
+
+using testing::_;
+using testing::SizeIs;
+using testing::NiceMock;
+using testing::AnyNumber;
+
+using ClangBackEnd::V2::ProjectPartContainer;
+using CppTools::ClangCompilerOptionsBuilder;
+
+class ProjectUpdater : public testing::Test
+{
+protected:
+ void SetUp() override;
+
+protected:
+ ClangPchManager::PchManagerClient pchManagerClient;
+ MockPchManagerNotifier mockPchManagerNotifier{pchManagerClient};
+ NiceMock<MockPchManagerServer> mockPchManagerServer;
+ ClangPchManager::ProjectUpdater updater{mockPchManagerServer, pchManagerClient};
+ Utils::SmallString projectPartId{"project1"};
+ Utils::SmallString projectPartId2{"project2"};
+ Utils::SmallStringVector headerPaths = {"/path/to/header1.h", "/path/to/header2.h"};
+ Utils::SmallStringVector sourcePaths = {"/path/to/source1.h", "/path/to/source2.h"};
+ CppTools::ProjectFile header1ProjectFile{headerPaths[0], CppTools::ProjectFile::CXXHeader};
+ CppTools::ProjectFile header2ProjectFile{headerPaths[1], CppTools::ProjectFile::CXXHeader};
+ CppTools::ProjectFile source1ProjectFile{sourcePaths[0], CppTools::ProjectFile::CXXSource};
+ CppTools::ProjectFile source2ProjectFile{sourcePaths[1], CppTools::ProjectFile::CXXSource};
+ CppTools::ProjectPart projectPart;
+ ProjectPartContainer expectedContainer;
+};
+
+TEST_F(ProjectUpdater, CallUpdatePchProjectParts)
+{
+ std::vector<CppTools::ProjectPart*> projectParts = {&projectPart, &projectPart};
+ ClangBackEnd::UpdatePchProjectPartsMessage message{{expectedContainer.clone(), expectedContainer.clone()}};
+
+ EXPECT_CALL(mockPchManagerServer, updatePchProjectParts(message));
+
+ updater.updateProjectParts(projectParts);
+}
+
+TEST_F(ProjectUpdater, CallRemovePchProjectParts)
+{
+ EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(_)).Times(AnyNumber());
+ ClangBackEnd::RemovePchProjectPartsMessage message{{projectPartId, projectPartId2}};
+
+ EXPECT_CALL(mockPchManagerServer, removePchProjectParts(message));
+
+ updater.removeProjectParts({projectPartId, projectPartId2});
+}
+
+TEST_F(ProjectUpdater, CallPrecompiledHeaderRemoved)
+{
+ ClangBackEnd::RemovePchProjectPartsMessage message{{projectPartId, projectPartId2}};
+
+ EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId.toQString()));
+ EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId2.toQString()));
+
+ updater.removeProjectParts({projectPartId, projectPartId2});
+}
+
+TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainer)
+{
+ auto container = updater.toProjectPartContainer(&projectPart);
+
+ ASSERT_THAT(container, expectedContainer);
+}
+
+TEST_F(ProjectUpdater, ConvertProjectPartToProjectPartContainersHaveSameSizeLikeProjectParts)
+{
+ auto containers = updater.toProjectPartContainers({&projectPart, &projectPart});
+
+ ASSERT_THAT(containers, SizeIs(2));
+}
+
+void ProjectUpdater::SetUp()
+{
+ projectPart.files.push_back(header1ProjectFile);
+ projectPart.files.push_back(header2ProjectFile);
+ projectPart.files.push_back(source1ProjectFile);
+ projectPart.files.push_back(source2ProjectFile);
+ projectPart.displayName = projectPartId;
+
+ Utils::SmallStringVector arguments{ClangCompilerOptionsBuilder::build(
+ &projectPart,
+ CppTools::ProjectFile::CXXHeader,
+ ClangCompilerOptionsBuilder::PchUsage::None,
+ CLANG_VERSION,
+ CLANG_RESOURCE_DIR
+ )};
+
+ expectedContainer = {projectPartId.clone(),
+ arguments.clone(),
+ headerPaths.clone(),
+ sourcePaths.clone()};
+}
+}
+
diff --git a/tests/unit/unittest/smallstring-test.cpp b/tests/unit/unittest/smallstring-test.cpp
index 863d2ec66e..3d68b4a812 100644
--- a/tests/unit/unittest/smallstring-test.cpp
+++ b/tests/unit/unittest/smallstring-test.cpp
@@ -101,6 +101,15 @@ TEST(SmallString, CreateFromSmallStringIterators)
ASSERT_THAT(text, SmallString("this is very very very very very much text"));
}
+TEST(SmallString, CreateFromStringView)
+{
+ SmallStringView sourceText = "this is very very very very very much text";
+
+ SmallString text(sourceText);
+
+ ASSERT_THAT(text, SmallString("this is very very very very very much text"));
+}
+
TEST(SmallString, ShortSmallStringIsReference)
{
SmallString longText("very very very very very long text");
@@ -658,6 +667,26 @@ TEST(SmallString, SmallerOperator)
ASSERT_FALSE(SmallString("text") < SmallString("text"));
}
+TEST(SmallString, SmallerOperatorWithStringViewRight)
+{
+ ASSERT_TRUE(SmallString() < SmallStringView("text"));
+ ASSERT_TRUE(SmallString("some") < SmallStringView("text"));
+ ASSERT_TRUE(SmallString("text") < SmallStringView("texta"));
+ ASSERT_FALSE(SmallString("texta") < SmallStringView("text"));
+ ASSERT_FALSE(SmallString("text") < SmallStringView("some"));
+ ASSERT_FALSE(SmallString("text") < SmallStringView("text"));
+}
+
+TEST(SmallString, SmallerOperatorWithStringViewLeft)
+{
+ ASSERT_TRUE(SmallStringView("") < SmallString("text"));
+ ASSERT_TRUE(SmallStringView("some") < SmallString("text"));
+ ASSERT_TRUE(SmallStringView("text") < SmallString("texta"));
+ ASSERT_FALSE(SmallStringView("texta") < SmallString("text"));
+ ASSERT_FALSE(SmallStringView("text") < SmallString("some"));
+ ASSERT_FALSE(SmallStringView("text") < SmallString("text"));
+}
+
TEST(SmallString, IsEmpty)
{
ASSERT_FALSE(SmallString("text").isEmpty());
diff --git a/tests/unit/unittest/stringcache-test.cpp b/tests/unit/unittest/stringcache-test.cpp
new file mode 100644
index 0000000000..92a2be71a3
--- /dev/null
+++ b/tests/unit/unittest/stringcache-test.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** 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.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <stringcache.h>
+
+#include <utils/smallstringio.h>
+
+namespace {
+
+using testing::ElementsAre;
+
+class StringCache : public testing::Test
+{
+protected:
+ ClangBackEnd::StringCache<Utils::PathString> cache;
+ Utils::PathString filePath1{"/file/pathOne"};
+ Utils::PathString filePath2{"/file/pathTwo"};
+ Utils::PathString filePath3{"/file/pathThree"};
+ Utils::PathString filePath4{"/file/pathFour"};
+};
+
+TEST_F(StringCache, AddFilePath)
+{
+ auto id = cache.stringId(filePath1);
+
+ ASSERT_THAT(id, 0);
+}
+
+TEST_F(StringCache, AddSecondFilePath)
+{
+ cache.stringId(filePath1);
+
+ auto id = cache.stringId(filePath2);
+
+ ASSERT_THAT(id, 1);
+}
+
+TEST_F(StringCache, AddDuplicateFilePath)
+{
+ cache.stringId(filePath1);
+
+ auto id = cache.stringId(filePath1);
+
+ ASSERT_THAT(id, 0);
+}
+
+TEST_F(StringCache, AddDuplicateFilePathBetweenOtherEntries)
+{
+ cache.stringId(filePath1);
+ cache.stringId(filePath2);
+ cache.stringId(filePath3);
+ cache.stringId(filePath4);
+
+ auto id = cache.stringId(filePath3);
+
+ ASSERT_THAT(id, 2);
+}
+
+TEST_F(StringCache, ThrowForGettingPathForNoEntry)
+{
+ EXPECT_ANY_THROW(cache.string(0));
+}
+
+TEST_F(StringCache, GetFilePathForIdWithOneEntry)
+{
+ cache.stringId(filePath1);
+
+ auto filePath = cache.string(0);
+
+ ASSERT_THAT(filePath, filePath1);
+}
+
+TEST_F(StringCache, GetFilePathForIdWithSomeEntries)
+{
+ cache.stringId(filePath1);
+ cache.stringId(filePath2);
+ cache.stringId(filePath3);
+ cache.stringId(filePath4);
+
+ auto filePath = cache.string(2);
+
+ ASSERT_THAT(filePath, filePath3);
+}
+
+TEST_F(StringCache, GetAllFilePaths)
+{
+ cache.stringId(filePath1);
+ cache.stringId(filePath2);
+ cache.stringId(filePath3);
+ cache.stringId(filePath4);
+
+ const auto &filePaths = cache.strings({0, 1, 2, 3});
+
+ ASSERT_THAT(filePaths, ElementsAre(filePath1, filePath2, filePath3, filePath4));
+}
+
+TEST_F(StringCache, AddFilePaths)
+{
+ auto ids = cache.stringIds({filePath1, filePath2, filePath3, filePath4});
+
+ ASSERT_THAT(ids, ElementsAre(0, 1, 2, 3));
+}
+
+}
diff --git a/tests/unit/unittest/testenvironment.h b/tests/unit/unittest/testenvironment.h
new file mode 100644
index 0000000000..f318116972
--- /dev/null
+++ b/tests/unit/unittest/testenvironment.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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
+
+#include <environment.h>
+
+#include <QTemporaryDir>
+
+class TestEnvironment final : public ClangBackEnd::Environment
+{
+public:
+ TestEnvironment() {
+ temporaryDirectory.setAutoRemove(true);
+ }
+ QString pchBuildDirectory() const override
+ {
+ return temporaryDirectory.path();
+ }
+
+ QString clangCompilerPath() const override
+ {
+ return QString::fromUtf8(CLANG_COMPILER_PATH);
+ }
+
+private:
+ QTemporaryDir temporaryDirectory;
+};
diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro
index 45ccba3bc1..9a902c53ba 100644
--- a/tests/unit/unittest/unittest.pro
+++ b/tests/unit/unittest/unittest.pro
@@ -44,7 +44,10 @@ SOURCES += \
clangreparsesupportivetranslationunitjob-test.cpp \
clangsupportivetranslationunitinitializer-test.cpp \
codecompleter-test.cpp \
- clientserveroutsideprocess-test.cpp
+ clientserveroutsideprocess-test.cpp \
+ clangpathwatcher-test.cpp \
+ projectparts-test.cpp \
+ stringcache-test.cpp
!isEmpty(LIBCLANG_LIBS) {
SOURCES += \
@@ -109,7 +112,13 @@ SOURCES += \
symbolfinder-test.cpp \
sourcerangeextractor-test.cpp \
gtest-clang-printing.cpp \
- testclangtool.cpp
+ testclangtool.cpp \
+ pchmanagerclientserverinprocess-test.cpp \
+ includecollector-test.cpp \
+ pchmanagerserver-test.cpp \
+ pchcreator-test.cpp \
+ pchmanagerclient-test.cpp \
+ projectupdater-test.cpp
}
exists($$GOOGLEBENCHMARK_DIR) {
@@ -131,7 +140,11 @@ HEADERS += \
mocksearchhandle.h \
compare-operators.h \
gtest-creator-printing.h \
- conditionally-disabled-tests.h
+ conditionally-disabled-tests.h \
+ mockqfilesystemwatcher.h \
+ mockclangpathwatcher.h \
+ mockprojectparts.h \
+ mockclangpathwatchernotifier.h
!isEmpty(LIBCLANG_LIBS) {
HEADERS += \
@@ -150,7 +163,12 @@ HEADERS += \
mockrefactoringclient.h \
mockrefactoringserver.h \
gtest-clang-printing.h \
- testclangtool.h
+ testclangtool.h \
+ mockpchmanagerserver.h \
+ mockpchmanagerclient.h \
+ testenvironment.h \
+ mockpchmanagernotifier.h \
+ mockpchcreator.h
}
OTHER_FILES += $$files(data/*)