Commit c072cdfb authored by Marco Bubke's avatar Marco Bubke

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's avatarEike Ziller <eike.ziller@qt.io>
Reviewed-by: Tim Jenssen's avatarTim Jenssen <tim.jenssen@qt.io>
parent d4b1cb4a
......@@ -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
......@@ -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>
......
/****************************************************************************
**
** 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
/****************************************************************************
**
** 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
/****************************************************************************
**
** 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
/****************************************************************************
**
** 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
/****************************************************************************
**
** 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
/****************************************************************************
**
** 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
/****************************************************************************
**
** 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
/****************************************************************************
**
** 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
/****************************************************************************
**
** 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
/****************************************************************************
**
** 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_;
}