aboutsummaryrefslogtreecommitdiffstats
path: root/src/tools/codemodelbackend
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@theqtcompany.com>2015-06-01 18:51:55 +0200
committerNikolai Kosjar <nikolai.kosjar@theqtcompany.com>2015-06-03 14:22:09 +0000
commite2f8a9883b84db38bdcd2dfca27ebe2bc2934ecb (patch)
tree909c5d415465ecfc2e2bf9a13126a24c4e2fddfc /src/tools/codemodelbackend
parent51fec1a3caa413b3d8901f45807d80a77554a017 (diff)
Introduce codemodelbackend process and library
This is a partial result of wip/clang-oop. More will follow. This allows us to invoke the completion out of the Qt Creator process and thus safes us as against libclang crashes. At this point only the completion use case is supported. Some notes on the individual components: src/libs/codemodelbackendipc * library encapsulating the inter process communication handling * used by the backend application and in a follow-up change by the creator integration src/libs/3rdparty/sqlite * version 3.8.10.2 * dependency of codemodelbackendipc, will be used to storage indexing data, among others src/tools/codemodelbackend * the backend application tests/unit: * unit tests Change-Id: I91a48e27467581a22fb760a18d8eb926008fea60 Reviewed-by: Alessandro Portale <alessandro.portale@theqtcompany.com> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> Reviewed-by: Marco Bubke <marco.bubke@theqtcompany.com> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
Diffstat (limited to 'src/tools/codemodelbackend')
-rw-r--r--src/tools/codemodelbackend/codemodelbackend.pri23
-rw-r--r--src/tools/codemodelbackend/codemodelbackend.pro6
-rw-r--r--src/tools/codemodelbackend/codemodelbackend.qbs30
-rw-r--r--src/tools/codemodelbackend/codemodelbackendmain.cpp61
-rw-r--r--src/tools/codemodelbackend/ipcsource/clangcodecompleteresults.cpp72
-rw-r--r--src/tools/codemodelbackend/ipcsource/clangcodecompleteresults.h63
-rw-r--r--src/tools/codemodelbackend/ipcsource/clangipcserver.cpp128
-rw-r--r--src/tools/codemodelbackend/ipcsource/clangipcserver.h67
-rw-r--r--src/tools/codemodelbackend/ipcsource/clangstring.cpp74
-rw-r--r--src/tools/codemodelbackend/ipcsource/clangstring.h62
-rw-r--r--src/tools/codemodelbackend/ipcsource/codecompletefailedexception.cpp37
-rw-r--r--src/tools/codemodelbackend/ipcsource/codecompletefailedexception.h41
-rw-r--r--src/tools/codemodelbackend/ipcsource/codecompleter.cpp78
-rw-r--r--src/tools/codemodelbackend/ipcsource/codecompleter.h61
-rw-r--r--src/tools/codemodelbackend/ipcsource/codecompletionchunkconverter.cpp97
-rw-r--r--src/tools/codemodelbackend/ipcsource/codecompletionchunkconverter.h61
-rw-r--r--src/tools/codemodelbackend/ipcsource/codecompletionsextractor.cpp285
-rw-r--r--src/tools/codemodelbackend/ipcsource/codecompletionsextractor.h84
-rw-r--r--src/tools/codemodelbackend/ipcsource/codemodelbackendclangipc-source.pri37
-rw-r--r--src/tools/codemodelbackend/ipcsource/projectcontainer.cpp99
-rw-r--r--src/tools/codemodelbackend/ipcsource/projectcontainer.h73
-rw-r--r--src/tools/codemodelbackend/ipcsource/projectpart.cpp158
-rw-r--r--src/tools/codemodelbackend/ipcsource/projectpart.h85
-rw-r--r--src/tools/codemodelbackend/ipcsource/projectpartsdonotexistexception.cpp56
-rw-r--r--src/tools/codemodelbackend/ipcsource/projectpartsdonotexistexception.h56
-rw-r--r--src/tools/codemodelbackend/ipcsource/projects.cpp105
-rw-r--r--src/tools/codemodelbackend/ipcsource/projects.h66
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunit.cpp230
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunit.h103
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunitdoesnotexistexception.cpp63
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunitdoesnotexistexception.h55
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunitfilenotexitexception.cpp56
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunitfilenotexitexception.h56
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunitisnullexception.cpp42
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunitisnullexception.h48
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunitparseerrorexception.cpp66
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunitparseerrorexception.h58
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunits.cpp150
-rw-r--r--src/tools/codemodelbackend/ipcsource/translationunits.h74
-rw-r--r--src/tools/codemodelbackend/ipcsource/unsavedfiles.cpp188
-rw-r--r--src/tools/codemodelbackend/ipcsource/unsavedfiles.h88
-rw-r--r--src/tools/codemodelbackend/unittests/clang/clang.pro26
-rw-r--r--src/tools/codemodelbackend/unittests/clang/foo.h40
-rw-r--r--src/tools/codemodelbackend/unittests/clang/tst_clang.cpp78
-rw-r--r--src/tools/codemodelbackend/unittests/codemodelbackendipc/codemodelbackendipc.pro5
-rw-r--r--src/tools/codemodelbackend/unittests/codemodelbackendipc/codemodelbackendipc_dependencies.pri2
-rw-r--r--src/tools/codemodelbackend/unittests/codemodelbackendprocess/codemodelbackendprocess.pro1
-rw-r--r--src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/clientdummy.cpp51
-rw-r--r--src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/clientdummy.h63
-rw-r--r--src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/codemodelbackendprocesstest.pro22
-rw-r--r--src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/foo.h40
-rw-r--r--src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/tst_codemodelbackendprocess.cpp104
-rw-r--r--src/tools/codemodelbackend/unittests/codemodelbackendprocesstestcommon.pri23
-rw-r--r--src/tools/codemodelbackend/unittests/codemodelbackendprocessunittests.pro8
54 files changed, 3805 insertions, 0 deletions
diff --git a/src/tools/codemodelbackend/codemodelbackend.pri b/src/tools/codemodelbackend/codemodelbackend.pri
new file mode 100644
index 0000000000..4e2620f3e1
--- /dev/null
+++ b/src/tools/codemodelbackend/codemodelbackend.pri
@@ -0,0 +1,23 @@
+QT += core network
+QT -= gui
+
+TARGET = codemodelbackend
+CONFIG += console
+CONFIG -= app_bundle C++-14
+
+TEMPLATE = app
+
+include(ipcsource/codemodelbackendclangipc-source.pri)
+include(../../../qtcreator.pri)
+include(../../shared/clang/clang_installation.pri)
+
+requires(!isEmpty(LLVM_INSTALL_DIR))
+
+LIBS += -L$$OUT_PWD/../codemodelbackendipc/lib/qtcreator -lCodemodelbackendipc -lSqlite
+LIBS += $$LLVM_LIBS
+INCLUDEPATH += $$LLVM_INCLUDEPATH
+
+INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/codemodelbackendipc
+INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/sqlite
+
+SOURCES += codemodelbackendmain.cpp
diff --git a/src/tools/codemodelbackend/codemodelbackend.pro b/src/tools/codemodelbackend/codemodelbackend.pro
new file mode 100644
index 0000000000..1e00d095c1
--- /dev/null
+++ b/src/tools/codemodelbackend/codemodelbackend.pro
@@ -0,0 +1,6 @@
+include(codemodelbackend.pri)
+
+DESTDIR = $$IDE_BIN_PATH
+target.path = /bin
+
+
diff --git a/src/tools/codemodelbackend/codemodelbackend.qbs b/src/tools/codemodelbackend/codemodelbackend.qbs
new file mode 100644
index 0000000000..e797119996
--- /dev/null
+++ b/src/tools/codemodelbackend/codemodelbackend.qbs
@@ -0,0 +1,30 @@
+import qbs 1.0
+import QtcClangInstallation as Clang
+import QtcProcessOutputReader
+
+QtcTool {
+ name: "codemodelbackend"
+
+ Depends { name: "CodeModelBackEndIpc" }
+
+ Group {
+ prefix: "ipcsource/"
+ files: [
+ "*.h",
+ "*.cpp"
+ ]
+ }
+
+ files: [ "codemodelbackendmain.cpp" ]
+
+ property string llvmConfig: Clang.llvmConfig(qbs)
+ property string llvmIncludeDir: Clang.includeDir(llvmConfig, QtcProcessOutputReader)
+ property string llvmLibDir: Clang.libDir(llvmConfig, QtcProcessOutputReader)
+ property string llvmLibs: Clang.libraries(qbs.targetOS)
+
+ condition: llvmConfig
+
+ cpp.includePaths: base.concat(["ipcsource", llvmIncludeDir])
+ cpp.libraryPaths: base.concat(llvmLibDir)
+ cpp.dynamicLibraries: base.concat(llvmLibs)
+}
diff --git a/src/tools/codemodelbackend/codemodelbackendmain.cpp b/src/tools/codemodelbackend/codemodelbackendmain.cpp
new file mode 100644
index 0000000000..398ebaaaf5
--- /dev/null
+++ b/src/tools/codemodelbackend/codemodelbackendmain.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include <QCoreApplication>
+
+#include <connectionserver.h>
+#include <cmbcommands.h>
+#include <clangipcserver.h>
+
+int main(int argc, char *argv[])
+{
+ QCoreApplication::setOrganizationName(QStringLiteral("QtProject"));
+ QCoreApplication::setOrganizationDomain(QStringLiteral("qt-project.org"));
+ QCoreApplication::setApplicationName(QStringLiteral("CodeModelBackend"));
+ QCoreApplication::setApplicationVersion(QStringLiteral("1.0.0"));
+
+ QCoreApplication application(argc, argv);
+
+ if (application.arguments().count() != 2) {
+ qWarning() << "wrong argument count";
+ return 1;
+ }
+
+ CodeModelBackEnd::Commands::registerCommands();
+
+ CodeModelBackEnd::ClangIpcServer clangIpcServer;
+ CodeModelBackEnd::ConnectionServer connectionServer(application.arguments()[1]);
+ connectionServer.start();
+ connectionServer.setIpcServer(&clangIpcServer);
+
+ return application.exec();
+}
+
+
diff --git a/src/tools/codemodelbackend/ipcsource/clangcodecompleteresults.cpp b/src/tools/codemodelbackend/ipcsource/clangcodecompleteresults.cpp
new file mode 100644
index 0000000000..3ea6957321
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/clangcodecompleteresults.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "clangcodecompleteresults.h"
+
+#include <memory>
+
+namespace CodeModelBackEnd {
+
+using std::swap;
+
+ClangCodeCompleteResults::ClangCodeCompleteResults(CXCodeCompleteResults *cxCodeCompleteResults)
+ : cxCodeCompleteResults(cxCodeCompleteResults)
+{
+}
+
+ClangCodeCompleteResults::~ClangCodeCompleteResults()
+{
+ clang_disposeCodeCompleteResults(cxCodeCompleteResults);
+}
+
+bool ClangCodeCompleteResults::isNull() const
+{
+ return cxCodeCompleteResults == nullptr;
+}
+
+CXCodeCompleteResults *ClangCodeCompleteResults::data() const
+{
+ return cxCodeCompleteResults;
+}
+
+ClangCodeCompleteResults &ClangCodeCompleteResults::operator =(ClangCodeCompleteResults &&clangCodeCompleteResults)
+{
+ swap(cxCodeCompleteResults, clangCodeCompleteResults.cxCodeCompleteResults);
+
+ return *this;
+}
+
+ClangCodeCompleteResults::ClangCodeCompleteResults(ClangCodeCompleteResults &&clangCodeCompleteResults)
+{
+ swap(cxCodeCompleteResults, clangCodeCompleteResults.cxCodeCompleteResults);
+}
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/clangcodecompleteresults.h b/src/tools/codemodelbackend/ipcsource/clangcodecompleteresults.h
new file mode 100644
index 0000000000..7e624d5cf9
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/clangcodecompleteresults.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_CLANGCODECOMPLETERESULTS_H
+#define CODEMODELBACKEND_CLANGCODECOMPLETERESULTS_H
+
+
+#include <clang-c/Index.h>
+
+#include <utf8string.h>
+
+namespace CodeModelBackEnd {
+
+class ClangCodeCompleteResults
+{
+public:
+ ClangCodeCompleteResults(CXCodeCompleteResults *cxCodeCompleteResults);
+ ~ClangCodeCompleteResults();
+
+ ClangCodeCompleteResults(const ClangCodeCompleteResults &ClangCodeCompleteResults) = delete;
+ const ClangCodeCompleteResults &operator =(const ClangCodeCompleteResults &ClangCodeCompleteResults) = delete;
+
+ ClangCodeCompleteResults(ClangCodeCompleteResults &&ClangCodeCompleteResults);
+ ClangCodeCompleteResults &operator =(ClangCodeCompleteResults &&ClangCodeCompleteResults);
+
+ bool isNull() const;
+
+ CXCodeCompleteResults *data() const;
+
+private:
+ CXCodeCompleteResults *cxCodeCompleteResults = nullptr;
+};
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_CLANGCODECOMPLETERESULTS_H
diff --git a/src/tools/codemodelbackend/ipcsource/clangipcserver.cpp b/src/tools/codemodelbackend/ipcsource/clangipcserver.cpp
new file mode 100644
index 0000000000..c385cfcd07
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/clangipcserver.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "clangipcserver.h"
+
+#include <QCoreApplication>
+
+#include <cmbregistertranslationunitsforcodecompletioncommand.h>
+#include <cmbunregistertranslationunitsforcodecompletioncommand.h>
+#include <cmbregisterprojectsforcodecompletioncommand.h>
+#include <cmbunregisterprojectsforcodecompletioncommand.h>
+#include <cmbcodecompletedcommand.h>
+#include <cmbcompletecodecommand.h>
+#include <translationunitdoesnotexistcommand.h>
+#include <projectpartsdonotexistcommand.h>
+
+#include "translationunits.h"
+#include "codecompleter.h"
+#include "translationunitdoesnotexistexception.h"
+#include "translationunitisnullexception.h"
+#include "translationunitfilenotexitexception.h"
+#include "projectpartsdonotexistexception.h"
+#include "translationunitparseerrorexception.h"
+
+#include <QDebug>
+
+namespace CodeModelBackEnd {
+
+ClangIpcServer::ClangIpcServer()
+ : translationUnits(projects, unsavedFiles)
+{
+}
+
+void ClangIpcServer::end()
+{
+ QCoreApplication::exit();
+}
+
+void ClangIpcServer::registerTranslationUnitsForCodeCompletion(const CodeModelBackEnd::RegisterTranslationUnitForCodeCompletionCommand &command)
+{
+ try {
+ translationUnits.createOrUpdate(command.fileContainers());
+ unsavedFiles.createOrUpdate(command.fileContainers());
+ } catch (const ProjectPartDoNotExistException &exception) {
+ client()->projectPartsDoNotExist(ProjectPartsDoNotExistCommand(exception.projectPartIds()));
+ } catch (const std::exception &exception) {
+ qWarning() << "Error in ClangIpcServer::registerTranslationUnitsForCodeCompletion:" << exception.what();
+ }
+}
+
+void ClangIpcServer::unregisterTranslationUnitsForCodeCompletion(const CodeModelBackEnd::UnregisterTranslationUnitsForCodeCompletionCommand &command)
+{
+ try {
+ translationUnits.remove(command.fileContainers());
+ } catch (const TranslationUnitDoesNotExistException &exception) {
+ client()->translationUnitDoesNotExist(TranslationUnitDoesNotExistCommand(exception.fileContainer()));
+ } catch (const ProjectPartDoNotExistException &exception) {
+ client()->projectPartsDoNotExist(ProjectPartsDoNotExistCommand(exception.projectPartIds()));
+ } catch (const std::exception &exception) {
+ qWarning() << "Error in ClangIpcServer::unregisterTranslationUnitsForCodeCompletion:" << exception.what();
+ }
+}
+
+void ClangIpcServer::registerProjectPartsForCodeCompletion(const RegisterProjectPartsForCodeCompletionCommand &command)
+{
+ try {
+ projects.createOrUpdate(command.projectContainers());
+ } catch (const std::exception &exception) {
+ qWarning() << "Error in ClangIpcServer::registerProjectPartsForCodeCompletion:" << exception.what();
+ }
+}
+
+void ClangIpcServer::unregisterProjectPartsForCodeCompletion(const UnregisterProjectPartsForCodeCompletionCommand &command)
+{
+ try {
+ projects.remove(command.filePaths());
+ } catch (const ProjectPartDoNotExistException &exception) {
+ client()->projectPartsDoNotExist(ProjectPartsDoNotExistCommand(exception.projectPartIds()));
+ } catch (const std::exception &exception) {
+ qWarning() << "Error in ClangIpcServer::unregisterProjectPartsForCodeCompletion:" << exception.what();
+ }
+}
+
+void ClangIpcServer::completeCode(const CodeModelBackEnd::CompleteCodeCommand &command)
+{
+ try {
+ CodeCompleter codeCompleter(translationUnits.translationUnit(command.filePath(), command.projectPartId()));
+
+ const auto codeCompletions = codeCompleter.complete(command.line(), command.column());
+
+ client()->codeCompleted(CodeCompletedCommand(codeCompletions, command.ticketNumber()));
+ } catch (const TranslationUnitDoesNotExistException &exception) {
+ client()->translationUnitDoesNotExist(TranslationUnitDoesNotExistCommand(exception.fileContainer()));
+ } catch (const ProjectPartDoNotExistException &exception) {
+ client()->projectPartsDoNotExist(ProjectPartsDoNotExistCommand(exception.projectPartIds()));
+ } catch (const std::exception &exception) {
+ qWarning() << "Error in ClangIpcServer::unregisterProjectPartsForCodeCompletion:" << exception.what();
+ }
+}
+
+}
diff --git a/src/tools/codemodelbackend/ipcsource/clangipcserver.h b/src/tools/codemodelbackend/ipcsource/clangipcserver.h
new file mode 100644
index 0000000000..10c7ebd8a7
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/clangipcserver.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CLANGIPCSERVER_H
+#define CLANGIPCSERVER_H
+
+#include "ipcserverinterface.h"
+
+#include "translationunit.h"
+#include "projectpart.h"
+#include "unsavedfiles.h"
+#include "projects.h"
+#include "translationunits.h"
+
+#include <utf8string.h>
+
+#include <QMap>
+
+namespace CodeModelBackEnd {
+
+class ClangIpcServer : public IpcServerInterface
+{
+public:
+ ClangIpcServer();
+
+ void end() override;
+ void registerTranslationUnitsForCodeCompletion(const RegisterTranslationUnitForCodeCompletionCommand &command) override;
+ void unregisterTranslationUnitsForCodeCompletion(const UnregisterTranslationUnitsForCodeCompletionCommand &command) override;
+ void registerProjectPartsForCodeCompletion(const RegisterProjectPartsForCodeCompletionCommand &command) override;
+ void unregisterProjectPartsForCodeCompletion(const UnregisterProjectPartsForCodeCompletionCommand &command) override;
+ void completeCode(const CompleteCodeCommand &command) override;
+
+private:
+ ProjectParts projects;
+ UnsavedFiles unsavedFiles;
+ TranslationUnits translationUnits;
+};
+
+} // namespace CodeModelBackEnd
+#endif // CLANGIPCSERVER_H
diff --git a/src/tools/codemodelbackend/ipcsource/clangstring.cpp b/src/tools/codemodelbackend/ipcsource/clangstring.cpp
new file mode 100644
index 0000000000..35006e0554
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/clangstring.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "clangstring.h"
+
+#include <memory>
+
+namespace CodeModelBackEnd {
+
+ClangString::ClangString(CXString cxString)
+ : cxString(cxString)
+{
+}
+
+ClangString::~ClangString()
+{
+ clang_disposeString(cxString);
+}
+
+bool ClangString::isNull() const
+{
+ return cxString.data == nullptr;
+}
+
+ClangString &ClangString::operator =(ClangString &&clangString)
+{
+ cxString = std::move(clangString.cxString);
+ clangString.cxString.data = nullptr;
+ clangString.cxString.private_flags = 0;
+
+ return *this;
+}
+
+ClangString::ClangString(ClangString &&clangString)
+ : cxString(std::move(clangString.cxString))
+{
+ clangString.cxString.data = nullptr;
+ clangString.cxString.private_flags = 0;
+}
+
+ClangString::operator Utf8String() const
+{
+ return Utf8String(clang_getCString(cxString), -1);
+}
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/clangstring.h b/src/tools/codemodelbackend/ipcsource/clangstring.h
new file mode 100644
index 0000000000..7dc498d765
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/clangstring.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_CLANGSTRING_H
+#define CODEMODELBACKEND_CLANGSTRING_H
+
+#include <clang-c/CXString.h>
+
+#include <utf8string.h>
+
+namespace CodeModelBackEnd {
+
+class ClangString
+{
+public:
+ ClangString(CXString cxString);
+ ~ClangString();
+
+ ClangString(const ClangString &clangString) = delete;
+ const ClangString &operator =(const ClangString &clangString) = delete;
+
+ ClangString(ClangString &&clangString);
+ ClangString &operator =(ClangString &&clangString);
+
+ operator Utf8String() const;
+
+ bool isNull() const;
+
+private:
+ CXString cxString;
+};
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_CLANGSTRING_H
diff --git a/src/tools/codemodelbackend/ipcsource/codecompletefailedexception.cpp b/src/tools/codemodelbackend/ipcsource/codecompletefailedexception.cpp
new file mode 100644
index 0000000000..f9b4231bbd
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/codecompletefailedexception.cpp
@@ -0,0 +1,37 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "codecompletefailedexception.h"
+
+CodeCompleteFailedException::CodeCompleteFailedException()
+{
+
+}
+
diff --git a/src/tools/codemodelbackend/ipcsource/codecompletefailedexception.h b/src/tools/codemodelbackend/ipcsource/codecompletefailedexception.h
new file mode 100644
index 0000000000..b792afd907
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/codecompletefailedexception.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODECOMPLETEFAILEDEXCEPTION_H
+#define CODECOMPLETEFAILEDEXCEPTION_H
+
+
+class CodeCompleteFailedException
+{
+public:
+ CodeCompleteFailedException();
+};
+
+#endif // CODECOMPLETEFAILEDEXCEPTION_H
diff --git a/src/tools/codemodelbackend/ipcsource/codecompleter.cpp b/src/tools/codemodelbackend/ipcsource/codecompleter.cpp
new file mode 100644
index 0000000000..1943d6fab8
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/codecompleter.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "codecompleter.h"
+
+#include "clangstring.h"
+#include "clangcodecompleteresults.h"
+#include "translationunit.h"
+#include "codecompletefailedexception.h"
+
+#include "codecompletionsextractor.h"
+
+#include <clang-c/Index.h>
+
+#include <QDebug>
+
+namespace CodeModelBackEnd {
+
+CodeCompleter::CodeCompleter(TranslationUnit translationUnit)
+ : translationUnit(std::move(translationUnit))
+{
+}
+
+QVector<CodeCompletion> CodeCompleter::complete(uint line, uint column)
+{
+ ClangCodeCompleteResults completeResults(clang_codeCompleteAt(translationUnit.cxTranslationUnit(),
+ translationUnit.filePath().constData(),
+ line,
+ column,
+ translationUnit.cxUnsavedFiles(),
+ translationUnit.unsavedFilesCount(),
+ CXCodeComplete_IncludeMacros | CXCodeComplete_IncludeCodePatterns));
+
+ CodeCompletionsExtractor extractor(completeResults.data());
+
+ return extractor.extractAll();
+}
+
+Utf8String CodeCompleter::filePath() const
+{
+ return translationUnit.filePath();
+}
+
+void CodeCompleter::checkCodeCompleteResult(CXCodeCompleteResults *completeResults)
+{
+ if (!completeResults)
+ throw CodeCompleteFailedException();
+}
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/codecompleter.h b/src/tools/codemodelbackend/ipcsource/codecompleter.h
new file mode 100644
index 0000000000..d47f131516
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/codecompleter.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_CODECOMPLETER_H
+#define CODEMODELBACKEND_CODECOMPLETER_H
+
+#include <codecompletion.h>
+#include <utf8stringvector.h>
+
+#include "translationunit.h"
+
+namespace CodeModelBackEnd {
+
+class TranslationUnit;
+
+class CodeCompleter
+{
+public:
+ CodeCompleter() = default;
+ CodeCompleter(TranslationUnit translationUnit);
+
+ QVector<CodeCompletion> complete(uint line, uint column);
+
+private:
+ Utf8String filePath() const;
+ static void checkCodeCompleteResult(CXCodeCompleteResults *completeResults);
+
+private:
+ TranslationUnit translationUnit;
+};
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_CODECOMPLETER_H
diff --git a/src/tools/codemodelbackend/ipcsource/codecompletionchunkconverter.cpp b/src/tools/codemodelbackend/ipcsource/codecompletionchunkconverter.cpp
new file mode 100644
index 0000000000..deda1fea0f
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/codecompletionchunkconverter.cpp
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "codecompletionchunkconverter.h"
+
+#include "clangstring.h"
+
+namespace CodeModelBackEnd {
+
+void CodeCompletionChunkConverter::extractCompletionChunks(CXCompletionString completionString)
+{
+ const uint completionChunkCount = clang_getNumCompletionChunks(completionString);
+
+ for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) {
+ const CodeCompletionChunk::Kind kind = chunkKind(completionString, chunkIndex);
+
+ if (kind == CodeCompletionChunk::Optional)
+ chunks.append(CodeCompletionChunk(kind,
+ chunkText(completionString, chunkIndex),
+ optionalChunks(completionString, chunkIndex)));
+ else
+ chunks.append(CodeCompletionChunk(kind,
+ chunkText(completionString, chunkIndex)));
+ }
+}
+
+void CodeCompletionChunkConverter::extractOptionalCompletionChunks(CXCompletionString completionString)
+{
+ const uint completionChunkCount = clang_getNumCompletionChunks(completionString);
+
+ for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) {
+ const CodeCompletionChunk::Kind kind = chunkKind(completionString, chunkIndex);
+
+ if (kind == CodeCompletionChunk::Optional)
+ extractOptionalCompletionChunks(clang_getCompletionChunkCompletionString(completionString, chunkIndex));
+ else
+ chunks.append(CodeCompletionChunk(kind, chunkText(completionString, chunkIndex)));
+ }
+}
+
+CodeCompletionChunk::Kind CodeCompletionChunkConverter::chunkKind(CXCompletionString completionString, uint chunkIndex)
+{
+ return CodeCompletionChunk::Kind(clang_getCompletionChunkKind(completionString, chunkIndex));
+}
+
+QVector<CodeCompletionChunk> CodeCompletionChunkConverter::extract(CXCompletionString completionString)
+{
+ CodeCompletionChunkConverter converter;
+
+ converter.extractCompletionChunks(completionString);
+
+ return converter.chunks;
+}
+
+Utf8String CodeCompletionChunkConverter::chunkText(CXCompletionString completionString, uint chunkIndex)
+{
+ return ClangString(clang_getCompletionChunkText(completionString, chunkIndex));
+}
+
+QVector<CodeCompletionChunk> CodeCompletionChunkConverter::optionalChunks(CXCompletionString completionString, uint chunkIndex)
+{
+ CodeCompletionChunkConverter converter;
+
+ converter.extractOptionalCompletionChunks(clang_getCompletionChunkCompletionString(completionString, chunkIndex));
+
+ return converter.chunks;
+}
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/codecompletionchunkconverter.h b/src/tools/codemodelbackend/ipcsource/codecompletionchunkconverter.h
new file mode 100644
index 0000000000..772cf8409e
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/codecompletionchunkconverter.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_CODECOMPLETIONCHUNKCONVERTER_H
+#define CODEMODELBACKEND_CODECOMPLETIONCHUNKCONVERTER_H
+
+#include <codecompletionchunk.h>
+
+#include <QVector>
+
+#include <clang-c/Index.h>
+
+namespace CodeModelBackEnd {
+
+class CodeCompletionChunkConverter
+{
+public:
+ static QVector<CodeCompletionChunk> extract(CXCompletionString completionString);
+
+ static Utf8String chunkText(CXCompletionString completionString, uint chunkIndex);
+
+private:
+ QVector<CodeCompletionChunk> optionalChunks(CXCompletionString completionString, uint chunkIndex);
+ static CodeCompletionChunk::Kind chunkKind(CXCompletionString completionString, uint chunkIndex);
+ void extractCompletionChunks(CXCompletionString completionString);
+ void extractOptionalCompletionChunks(CXCompletionString completionString);
+
+private:
+ QVector<CodeCompletionChunk> chunks;
+};
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_CODECOMPLETIONCHUNKCONVERTER_H
diff --git a/src/tools/codemodelbackend/ipcsource/codecompletionsextractor.cpp b/src/tools/codemodelbackend/ipcsource/codecompletionsextractor.cpp
new file mode 100644
index 0000000000..b6e28b02d3
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/codecompletionsextractor.cpp
@@ -0,0 +1,285 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "codecompletionsextractor.h"
+
+#include "clangstring.h"
+#include "codecompletionchunkconverter.h"
+
+#ifdef CODEMODELBACKEND_TESTS
+#include <gtest/gtest.h>
+#endif
+
+#include <QDebug>
+
+namespace CodeModelBackEnd {
+
+CodeCompletionsExtractor::CodeCompletionsExtractor(CXCodeCompleteResults *cxCodeCompleteResults)
+ : cxCodeCompleteResults(cxCodeCompleteResults)
+{
+
+}
+
+bool CodeCompletionsExtractor::next()
+{
+ const uint cxCodeCompleteResultCount = cxCodeCompleteResults->NumResults;
+
+ ++cxCodeCompleteResultIndex;
+
+ if (cxCodeCompleteResultIndex < cxCodeCompleteResultCount) {
+ currentCxCodeCompleteResult = cxCodeCompleteResults->Results[cxCodeCompleteResultIndex];
+
+ currentCodeCompletion_ = CodeCompletion();
+
+ extractCompletionKind();
+ extractText();
+ extractPriority();
+ extractAvailability();
+ extractHasParameters();
+ extractCompletionChunks();
+
+ return true;
+ }
+
+ return false;
+}
+
+bool CodeCompletionsExtractor::peek(const Utf8String &name)
+{
+ const uint cxCodeCompleteResultCount = cxCodeCompleteResults->NumResults;
+
+ uint peekCxCodeCompleteResultIndex = cxCodeCompleteResultIndex + 1;
+
+ while (peekCxCodeCompleteResultIndex < cxCodeCompleteResultCount) {
+ if (hasText(name, cxCodeCompleteResults->Results[peekCxCodeCompleteResultIndex].CompletionString))
+ return true;
+
+ ++peekCxCodeCompleteResultIndex;
+ }
+
+ return false;
+}
+
+QVector<CodeCompletion> CodeCompletionsExtractor::extractAll()
+{
+ QVector<CodeCompletion> codeCompletions;
+
+ while (next())
+ codeCompletions.append(currentCodeCompletion_);
+
+ return codeCompletions;
+}
+
+void CodeCompletionsExtractor::extractCompletionKind()
+{
+ switch (currentCxCodeCompleteResult.CursorKind) {
+ case CXCursor_FunctionTemplate:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::TemplateFunctionCompletionKind);
+ break;
+ case CXCursor_CXXMethod:
+ extractMethodCompletionKind();
+ break;
+ case CXCursor_FunctionDecl:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::FunctionCompletionKind);
+ break;
+ case CXCursor_VariableRef:
+ case CXCursor_VarDecl:
+ case CXCursor_FieldDecl:
+ case CXCursor_ParmDecl:
+ case CXCursor_NonTypeTemplateParameter:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::VariableCompletionKind);
+ break;
+ case CXCursor_StructDecl:
+ case CXCursor_UnionDecl:
+ case CXCursor_ClassDecl:
+ case CXCursor_TemplateTypeParameter:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::ClassCompletionKind);
+ break;
+ case CXCursor_ClassTemplatePartialSpecialization:
+ case CXCursor_ClassTemplate:
+ case CXCursor_TemplateTemplateParameter:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::TemplateClassCompletionKind);
+ break;
+ case CXCursor_Namespace:
+ case CXCursor_NamespaceAlias:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::NamespaceCompletionKind);
+ break;
+ case CXCursor_EnumDecl:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::EnumerationCompletionKind);
+ break;
+ case CXCursor_EnumConstantDecl:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::EnumeratorCompletionKind);
+ break;
+ case CXCursor_Constructor:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::ConstructorCompletionKind);
+ break;
+ case CXCursor_Destructor:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::DestructorCompletionKind);
+ break;
+ case CXCursor_MacroDefinition:
+ extractMacroCompletionKind();
+ break;
+ case CXCursor_NotImplemented:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::KeywordCompletionKind);
+ break;
+ default:
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::Other);
+ }
+}
+
+void CodeCompletionsExtractor::extractText()
+{
+ const uint completionChunkCount = clang_getNumCompletionChunks(currentCxCodeCompleteResult.CompletionString);
+ for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) {
+ const CXCompletionChunkKind chunkKind = clang_getCompletionChunkKind(currentCxCodeCompleteResult.CompletionString, chunkIndex);
+ if (chunkKind == CXCompletionChunk_TypedText) {
+ currentCodeCompletion_.setText(CodeCompletionChunkConverter::chunkText(currentCxCodeCompleteResult.CompletionString, chunkIndex));
+ break;
+ }
+ }
+}
+
+void CodeCompletionsExtractor::extractMethodCompletionKind()
+{
+ CXCompletionString cxCompletionString = cxCodeCompleteResults->Results[cxCodeCompleteResultIndex].CompletionString;
+ const uint annotationCount = clang_getCompletionNumAnnotations(cxCompletionString);
+
+ for (uint annotationIndex = 0; annotationIndex < annotationCount; ++annotationIndex) {
+ ClangString annotation = clang_getCompletionAnnotation(cxCompletionString, annotationIndex);
+
+ if (annotation == Utf8StringLiteral("qt_signal")) {
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::SignalCompletionKind);
+ return;
+ }
+
+ if (annotation == Utf8StringLiteral("qt_slot")) {
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::SlotCompletionKind);
+ return;
+ }
+ }
+
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::FunctionCompletionKind);
+}
+
+void CodeCompletionsExtractor::extractMacroCompletionKind()
+{
+ CXCompletionString cxCompletionString = cxCodeCompleteResults->Results[cxCodeCompleteResultIndex].CompletionString;
+
+ const uint completionChunkCount = clang_getNumCompletionChunks(cxCompletionString);
+
+ for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) {
+ CXCompletionChunkKind kind = clang_getCompletionChunkKind(cxCompletionString, chunkIndex);
+ if (kind == CXCompletionChunk_Placeholder) {
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::FunctionCompletionKind);
+ return;
+ }
+ }
+
+ currentCodeCompletion_.setCompletionKind(CodeCompletion::PreProcessorCompletionKind);
+}
+
+void CodeCompletionsExtractor::extractPriority()
+{
+ CXCompletionString cxCompletionString = cxCodeCompleteResults->Results[cxCodeCompleteResultIndex].CompletionString;
+ quint32 priority = clang_getCompletionPriority(cxCompletionString);
+ currentCodeCompletion_.setPriority(priority);
+}
+
+void CodeCompletionsExtractor::extractAvailability()
+{
+ CXCompletionString cxCompletionString = cxCodeCompleteResults->Results[cxCodeCompleteResultIndex].CompletionString;
+ CXAvailabilityKind cxAvailabilityKind = clang_getCompletionAvailability(cxCompletionString);
+
+ switch (cxAvailabilityKind) {
+ case CXAvailability_Available:
+ currentCodeCompletion_.setAvailability(CodeCompletion::Available);
+ break;
+ case CXAvailability_Deprecated:
+ currentCodeCompletion_.setAvailability(CodeCompletion::Deprecated);
+ break;
+ case CXAvailability_NotAvailable:
+ currentCodeCompletion_.setAvailability(CodeCompletion::NotAvailable);
+ break;
+ case CXAvailability_NotAccessible:
+ currentCodeCompletion_.setAvailability(CodeCompletion::NotAccessible);
+ break;
+ }
+}
+
+void CodeCompletionsExtractor::extractHasParameters()
+{
+ const uint completionChunkCount = clang_getNumCompletionChunks(currentCxCodeCompleteResult.CompletionString);
+ for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) {
+ const CXCompletionChunkKind chunkKind = clang_getCompletionChunkKind(currentCxCodeCompleteResult.CompletionString, chunkIndex);
+ if (chunkKind == CXCompletionChunk_LeftParen) {
+ const CXCompletionChunkKind nextChunkKind = clang_getCompletionChunkKind(currentCxCodeCompleteResult.CompletionString, chunkIndex + 1);
+ currentCodeCompletion_.setHasParameters(nextChunkKind != CXCompletionChunk_RightParen);
+ return;
+ }
+ }
+}
+
+void CodeCompletionsExtractor::extractCompletionChunks()
+{
+ currentCodeCompletion_.setChunks(CodeCompletionChunkConverter::extract(currentCxCodeCompleteResult.CompletionString));
+}
+
+bool CodeCompletionsExtractor::hasText(const Utf8String &text, CXCompletionString cxCompletionString) const
+{
+ const uint completionChunkCount = clang_getNumCompletionChunks(cxCompletionString);
+
+ for (uint chunkIndex = 0; chunkIndex < completionChunkCount; ++chunkIndex) {
+ const CXCompletionChunkKind chunkKind = clang_getCompletionChunkKind(cxCompletionString, chunkIndex);
+ if (chunkKind == CXCompletionChunk_TypedText) {
+ const ClangString currentText(clang_getCompletionChunkText(cxCompletionString, chunkIndex));
+ return text == currentText;
+ }
+ }
+
+ return false;
+}
+
+const CodeCompletion &CodeCompletionsExtractor::currentCodeCompletion() const
+{
+ return currentCodeCompletion_;
+}
+
+#ifdef CODEMODELBACKEND_TESTS
+void PrintTo(const CodeCompletionsExtractor &extractor, std::ostream *os)
+{
+ *os << "name: " << ::testing::PrintToString(extractor.currentCodeCompletion().text())
+ << ", kind: " << ::testing::PrintToString(extractor.currentCodeCompletion().completionKind())
+ << ", priority: " << extractor.currentCodeCompletion().priority()
+ << ", kind: " << ::testing::PrintToString(extractor.currentCodeCompletion().availability());
+}
+#endif
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/codecompletionsextractor.h b/src/tools/codemodelbackend/ipcsource/codecompletionsextractor.h
new file mode 100644
index 0000000000..a7ce33d587
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/codecompletionsextractor.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_CODECOMPLETIONSEXTRACTOR_H
+#define CODEMODELBACKEND_CODECOMPLETIONSEXTRACTOR_H
+
+#include <clang-c/Index.h>
+
+#include <QVector>
+
+#include <codecompletion.h>
+
+namespace CodeModelBackEnd {
+
+class CodeCompletionsExtractor
+{
+public:
+ CodeCompletionsExtractor(CXCodeCompleteResults *cxCodeCompleteResults);
+
+ CodeCompletionsExtractor(CodeCompletionsExtractor&) = delete;
+ CodeCompletionsExtractor &operator =(CodeCompletionsExtractor&) = delete;
+
+ CodeCompletionsExtractor(CodeCompletionsExtractor&&) = delete;
+ CodeCompletionsExtractor &operator =(CodeCompletionsExtractor&&) = delete;
+
+ bool next();
+ bool peek(const Utf8String &name);
+
+ QVector<CodeCompletion> extractAll();
+
+ const CodeCompletion &currentCodeCompletion() const;
+
+private:
+ void extractCompletionKind();
+ void extractText();
+ void extractMethodCompletionKind();
+ void extractMacroCompletionKind();
+ void extractPriority();
+ void extractAvailability();
+ void extractHasParameters();
+ void extractCompletionChunks();
+
+ bool hasText(const Utf8String &text, CXCompletionString cxCompletionString) const;
+
+private:
+ CodeCompletion currentCodeCompletion_;
+ CXCompletionResult currentCxCodeCompleteResult;
+ CXCodeCompleteResults *cxCodeCompleteResults;
+ uint cxCodeCompleteResultIndex = -1;
+};
+
+#ifdef CODEMODELBACKEND_TESTS
+void PrintTo(const CodeCompletionsExtractor &extractor, ::std::ostream* os);
+#endif
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_CODECOMPLETIONSEXTRACTOR_H
diff --git a/src/tools/codemodelbackend/ipcsource/codemodelbackendclangipc-source.pri b/src/tools/codemodelbackend/ipcsource/codemodelbackendclangipc-source.pri
new file mode 100644
index 0000000000..4e8800de02
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/codemodelbackendclangipc-source.pri
@@ -0,0 +1,37 @@
+INCLUDEPATH += $$PWD
+
+HEADERS += $$PWD/clangipcserver.h \
+ $$PWD/codecompleter.h \
+ $$PWD/clangstring.h \
+ $$PWD/translationunit.h \
+ $$PWD/translationunitisnullexception.h \
+ $$PWD/codecompletefailedexception.h \
+ $$PWD/clangcodecompleteresults.h \
+ $$PWD/codecompletionsextractor.h \
+ $$PWD/unsavedfiles.h \
+ $$PWD/projects.h \
+ $$PWD/translationunits.h \
+ $$PWD/translationunitparseerrorexception.h \
+ $$PWD/projectpart.h \
+ $$PWD/translationunitfilenotexitexception.h \
+ $$PWD/translationunitdoesnotexistexception.h \
+ $$PWD/projectpartsdonotexistexception.h \
+ $$PWD/codecompletionchunkconverter.h
+
+SOURCES += $$PWD/clangipcserver.cpp \
+ $$PWD/codecompleter.cpp \
+ $$PWD/clangstring.cpp \
+ $$PWD/translationunit.cpp \
+ $$PWD/translationunitisnullexception.cpp \
+ $$PWD/codecompletefailedexception.cpp \
+ $$PWD/clangcodecompleteresults.cpp \
+ $$PWD/codecompletionsextractor.cpp \
+ $$PWD/unsavedfiles.cpp \
+ $$PWD/projects.cpp \
+ $$PWD/translationunits.cpp \
+ $$PWD/translationunitparseerrorexception.cpp \
+ $$PWD/projectpart.cpp \
+ $$PWD/translationunitfilenotexitexception.cpp \
+ $$PWD/translationunitdoesnotexistexception.cpp \
+ $$PWD/projectpartsdonotexistexception.cpp \
+ $$PWD/codecompletionchunkconverter.cpp
diff --git a/src/tools/codemodelbackend/ipcsource/projectcontainer.cpp b/src/tools/codemodelbackend/ipcsource/projectcontainer.cpp
new file mode 100644
index 0000000000..8d7cff15f8
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/projectcontainer.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "projectcontainer.h"
+
+#include <QtDebug>
+
+namespace CodeModelBackEnd {
+
+ProjectPartContainer::ProjectPartContainer(const Utf8String &fileName,
+ const Utf8StringVector &arguments)
+ : projectPartId_(fileName),
+ arguments_(arguments)
+{
+}
+
+const Utf8String &ProjectPartContainer::projectPartId() const
+{
+ return projectPartId_;
+}
+
+const Utf8StringVector &ProjectPartContainer::arguments() const
+{
+ return arguments_;
+}
+
+
+QDataStream &operator<<(QDataStream &out, const ProjectPartContainer &container)
+{
+ out << container.projectPartId_;
+ out << container.arguments_;
+
+ return out;
+}
+
+QDataStream &operator>>(QDataStream &in, ProjectPartContainer &container)
+{
+ in >> container.projectPartId_;
+ in >> container.arguments_;
+
+ return in;
+}
+
+bool operator == (const ProjectPartContainer &first, const ProjectPartContainer &second)
+{
+ return first.projectPartId_ == second.projectPartId_;
+}
+
+bool operator < (const ProjectPartContainer &first, const ProjectPartContainer &second)
+{
+ return first.projectPartId_ < second.projectPartId_;
+}
+
+QDebug operator <<(QDebug debug, const ProjectPartContainer &container)
+{
+ debug.nospace() << "ProjectContainer("
+ << container.projectPartId()
+ << ")";
+
+ return debug;
+}
+
+void PrintTo(const ProjectPartContainer &container, ::std::ostream* os)
+{
+ *os << "ProjectContainer("
+ << container.projectPartId().constData()
+ << ")";
+}
+
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/projectcontainer.h b/src/tools/codemodelbackend/ipcsource/projectcontainer.h
new file mode 100644
index 0000000000..ed2f2f9680
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/projectcontainer.h
@@ -0,0 +1,73 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_PROJECTCONTAINER_H
+#define CODEMODELBACKEND_PROJECTCONTAINER_H
+
+#include <QMetaType>
+
+#include <utf8stringvector.h>
+
+#include <codemodelbackendipc_global.h>
+
+namespace CodeModelBackEnd {
+
+class CMBIPC_EXPORT ProjectPartContainer
+{
+ friend CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const ProjectPartContainer &container);
+ friend CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, ProjectPartContainer &container);
+ friend CMBIPC_EXPORT bool operator == (const ProjectPartContainer &first, const ProjectPartContainer &second);
+ friend CMBIPC_EXPORT bool operator < (const ProjectPartContainer &first, const ProjectPartContainer &second);
+public:
+ ProjectPartContainer() = default;
+ ProjectPartContainer(const Utf8String &projectPartId,
+ const Utf8StringVector &arguments = Utf8StringVector());
+
+ const Utf8String &projectPartId() const;
+ const Utf8StringVector &arguments() const;
+
+private:
+ Utf8String projectPartId_;
+ Utf8StringVector arguments_;
+};
+
+CMBIPC_EXPORT QDataStream &operator<<(QDataStream &out, const ProjectPartContainer &container);
+CMBIPC_EXPORT QDataStream &operator>>(QDataStream &in, ProjectPartContainer &container);
+CMBIPC_EXPORT bool operator == (const ProjectPartContainer &first, const ProjectPartContainer &second);
+CMBIPC_EXPORT bool operator < (const ProjectPartContainer &first, const ProjectPartContainer &second);
+
+CMBIPC_EXPORT QDebug operator <<(QDebug debug, const ProjectPartContainer &container);
+void PrintTo(const ProjectPartContainer &container, ::std::ostream* os);
+
+} // namespace CodeModelBackEnd
+
+Q_DECLARE_METATYPE(CodeModelBackEnd::ProjectPartContainer)
+
+#endif // CODEMODELBACKEND_PROJECTCONTAINER_H
diff --git a/src/tools/codemodelbackend/ipcsource/projectpart.cpp b/src/tools/codemodelbackend/ipcsource/projectpart.cpp
new file mode 100644
index 0000000000..896e52445f
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/projectpart.cpp
@@ -0,0 +1,158 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "projectpart.h"
+
+#include <cstring>
+
+#include <utf8stringvector.h>
+
+#include <projectpartcontainer.h>
+
+namespace CodeModelBackEnd {
+
+class ProjectPartData {
+public:
+ ProjectPartData(const Utf8String &projectPartId);
+ ~ProjectPartData();
+
+public:
+ void clearArguments();
+
+public:
+ time_point lastChangeTimePoint;
+ std::vector<const char*> arguments;
+ Utf8String projectPartId;
+};
+
+void ProjectPartData::clearArguments()
+{
+ for (auto argument : arguments)
+ delete [] argument;
+
+ arguments.clear();
+}
+
+ProjectPartData::ProjectPartData(const Utf8String &projectPartId)
+ : lastChangeTimePoint(std::chrono::steady_clock::now()),
+ projectPartId(projectPartId)
+{
+}
+
+ProjectPartData::~ProjectPartData()
+{
+ clearArguments();
+}
+
+ProjectPart::ProjectPart(const Utf8String &projectPartId)
+ : d(std::make_shared<ProjectPartData>(projectPartId))
+{
+}
+
+ProjectPart::ProjectPart(const ProjectPartContainer &projectContainer)
+ : d(std::make_shared<ProjectPartData>(projectContainer.projectPartId()))
+{
+ setArguments(projectContainer.arguments());
+}
+
+ProjectPart::~ProjectPart() = default;
+ProjectPart::ProjectPart(const ProjectPart &) = default;
+ProjectPart &ProjectPart::operator =(const ProjectPart &) = default;
+
+ProjectPart::ProjectPart(ProjectPart &&other)
+ : d(std::move(other.d))
+{
+}
+
+ProjectPart &ProjectPart::operator =(ProjectPart &&other)
+{
+ d = std::move(other.d);
+
+ return *this;
+}
+
+void ProjectPart::clearProjectPartId()
+{
+ d->projectPartId.clear();
+}
+
+const Utf8String &ProjectPart::projectPartId() const
+{
+ return d->projectPartId;
+}
+
+static const char *strdup(const Utf8String &utf8String)
+{
+ char *cxArgument = new char[utf8String.byteSize() + 1];
+ std::memcpy(cxArgument, utf8String.constData(), utf8String.byteSize() + 1);
+
+ return cxArgument;
+}
+
+void ProjectPart::setArguments(const Utf8StringVector &arguments)
+{
+ d->clearArguments();
+ d->arguments.resize(arguments.size());
+ std::transform(arguments.cbegin(), arguments.cend(), d->arguments.begin(), strdup);
+ updateLastChangeTimePoint();
+}
+
+const std::vector<const char*> &ProjectPart::arguments() const
+{
+ return d->arguments;
+}
+
+int ProjectPart::argumentCount() const
+{
+ return d->arguments.size();
+}
+
+const char * const *ProjectPart::cxArguments() const
+{
+ return arguments().data();
+}
+
+const time_point &ProjectPart::lastChangeTimePoint() const
+{
+ return d->lastChangeTimePoint;
+}
+
+void ProjectPart::updateLastChangeTimePoint()
+{
+ d->lastChangeTimePoint = std::chrono::steady_clock::now();
+}
+
+bool operator ==(const ProjectPart &first, const ProjectPart &second)
+{
+ return first.projectPartId() == second.projectPartId();
+}
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/projectpart.h b/src/tools/codemodelbackend/ipcsource/projectpart.h
new file mode 100644
index 0000000000..8a96fbc409
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/projectpart.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_PROJECT_H
+#define CODEMODELBACKEND_PROJECT_H
+
+#include <memory>
+#include <vector>
+#include <chrono>
+
+class Utf8String;
+class Utf8StringVector;
+
+namespace CodeModelBackEnd {
+
+class ProjectPartContainer;
+class ProjectPartData;
+
+using time_point = std::chrono::steady_clock::time_point;
+
+class ProjectPart
+{
+public:
+ ProjectPart(const Utf8String &projectPartId);
+ ProjectPart(const ProjectPartContainer &projectContainer);
+ ~ProjectPart();
+
+ ProjectPart(const ProjectPart &project);
+ ProjectPart &operator =(const ProjectPart &project);
+
+ ProjectPart(ProjectPart &&project);
+ ProjectPart &operator =(ProjectPart &&project);
+
+ void clearProjectPartId();
+
+ const Utf8String &projectPartId() const;
+
+ void setArguments(const Utf8StringVector &arguments_);
+
+ const std::vector<const char*> &arguments() const;
+
+ int argumentCount() const;
+ const char *const *cxArguments() const;
+
+ const time_point &lastChangeTimePoint() const;
+
+private:
+ void updateLastChangeTimePoint();
+
+private:
+ std::shared_ptr<ProjectPartData> d;
+};
+
+bool operator ==(const ProjectPart &first, const ProjectPart &second);
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_PROJECT_H
diff --git a/src/tools/codemodelbackend/ipcsource/projectpartsdonotexistexception.cpp b/src/tools/codemodelbackend/ipcsource/projectpartsdonotexistexception.cpp
new file mode 100644
index 0000000000..a896481ca0
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/projectpartsdonotexistexception.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "projectpartsdonotexistexception.h"
+
+namespace CodeModelBackEnd {
+
+ProjectPartDoNotExistException::ProjectPartDoNotExistException(const Utf8StringVector &projectPartIds)
+ : projectPartIds_(projectPartIds)
+{
+}
+
+const Utf8StringVector &ProjectPartDoNotExistException::projectPartIds() const
+{
+ return projectPartIds_;
+}
+
+const char *ProjectPartDoNotExistException::what() const Q_DECL_NOEXCEPT
+{
+ if (what_.isEmpty())
+ what_ += Utf8StringLiteral("ProjectPart files ")
+ + projectPartIds().join(Utf8StringLiteral(", "))
+ + Utf8StringLiteral(" does not exist!");
+
+ return what_.constData();
+}
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/projectpartsdonotexistexception.h b/src/tools/codemodelbackend/ipcsource/projectpartsdonotexistexception.h
new file mode 100644
index 0000000000..4e7010f8e6
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/projectpartsdonotexistexception.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_PROJECTDONOTEXISTSEXCEPTION_H
+#define CODEMODELBACKEND_PROJECTDONOTEXISTSEXCEPTION_H
+
+#include <utf8stringvector.h>
+
+#include <exception>
+
+namespace CodeModelBackEnd {
+
+class ProjectPartDoNotExistException : public std::exception
+{
+public:
+ ProjectPartDoNotExistException(const Utf8StringVector &projectPartIds);
+
+ const Utf8StringVector &projectPartIds() const;
+
+ const char *what() const Q_DECL_NOEXCEPT override;
+
+private:
+ Utf8StringVector projectPartIds_;
+ mutable Utf8String what_;
+};
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_PROJECTDONOTEXISTSEXCEPTION_H
diff --git a/src/tools/codemodelbackend/ipcsource/projects.cpp b/src/tools/codemodelbackend/ipcsource/projects.cpp
new file mode 100644
index 0000000000..2e2aa4afb4
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/projects.cpp
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "projects.h"
+
+#include <QtGlobal>
+
+#include "projectpartsdonotexistexception.h"
+
+namespace CodeModelBackEnd {
+
+void ProjectParts::createOrUpdate(const QVector<ProjectPartContainer> &projectContainers)
+{
+ for (const ProjectPartContainer &projectContainer : projectContainers)
+ createOrUpdateProjectPart(projectContainer);
+}
+
+void ProjectParts::remove(const Utf8StringVector &projectPartIds)
+{
+ Utf8StringVector processedProjectPartFilePaths = projectPartIds;
+
+ auto removeBeginIterator = std::remove_if(projects_.begin(), projects_.end(), [&processedProjectPartFilePaths] (const ProjectPart &project) {
+ return processedProjectPartFilePaths.removeFast(project.projectPartId());
+ });
+
+ std::for_each(removeBeginIterator, projects_.end(), [](ProjectPart &project) { project.clearProjectPartId(); });
+ projects_.erase(removeBeginIterator, projects_.end());
+
+ if (!processedProjectPartFilePaths.isEmpty())
+ throw ProjectPartDoNotExistException(processedProjectPartFilePaths);
+}
+
+bool ProjectParts::hasProjectPart(const Utf8String &projectPartId) const
+{
+ return findProjectPart(projectPartId) != projects_.cend();
+}
+
+const ProjectPart &ProjectParts::project(const Utf8String &projectPartId) const
+{
+ const auto findIterator = findProjectPart(projectPartId);
+
+ if (findIterator == projects_.cend())
+ throw ProjectPartDoNotExistException({projectPartId});
+
+ return *findIterator;
+}
+
+std::vector<ProjectPart>::const_iterator ProjectParts::findProjectPart(const Utf8String &projectPartId) const
+{
+ return std::find_if(projects_.begin(), projects_.end(), [projectPartId] (const ProjectPart &project) {
+ return project.projectPartId() == projectPartId;
+ });
+}
+
+std::vector<ProjectPart>::iterator ProjectParts::findProjectPart(const Utf8String &projectPartId)
+{
+ return std::find_if(projects_.begin(), projects_.end(), [projectPartId] (const ProjectPart &project) {
+ return project.projectPartId() == projectPartId;
+ });
+}
+
+const std::vector<ProjectPart> &ProjectParts::projects() const
+{
+ return projects_;
+}
+
+void ProjectParts::createOrUpdateProjectPart(const ProjectPartContainer &projectContainer)
+{
+ auto findIterator = findProjectPart(projectContainer.projectPartId());
+ if (findIterator == projects_.cend())
+ projects_.push_back(ProjectPart(projectContainer));
+ else
+ findIterator->setArguments(projectContainer.arguments());
+}
+
+
+} // namespace CodeModelbackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/projects.h b/src/tools/codemodelbackend/ipcsource/projects.h
new file mode 100644
index 0000000000..b63cc02874
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/projects.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_PROJECTS_H
+#define CODEMODELBACKEND_PROJECTS_H
+
+#include <projectpartcontainer.h>
+
+#include "projectpart.h"
+
+#include <vector>
+
+namespace CodeModelBackEnd {
+
+class ProjectParts
+{
+public:
+ void createOrUpdate(const QVector<ProjectPartContainer> &projectConainers);
+ void remove(const Utf8StringVector &projectPartIds);
+
+ bool hasProjectPart(const Utf8String &projectPartId) const;
+
+ const ProjectPart &project(const Utf8String &projectPartId) const;
+
+ std::vector<ProjectPart>::const_iterator findProjectPart(const Utf8String &projectPartId) const;
+ std::vector<ProjectPart>::iterator findProjectPart(const Utf8String &projectPartId);
+
+ const std::vector<ProjectPart> &projects() const;
+
+private:
+ void createOrUpdateProjectPart(const ProjectPartContainer &projectConainer);
+
+private:
+ std::vector<ProjectPart> projects_;
+};
+
+} // namespace CodeModelbackEnd
+
+#endif // CODEMODELBACKEND_PROJECTS_H
diff --git a/src/tools/codemodelbackend/ipcsource/translationunit.cpp b/src/tools/codemodelbackend/ipcsource/translationunit.cpp
new file mode 100644
index 0000000000..519e2f7aa2
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunit.cpp
@@ -0,0 +1,230 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "translationunit.h"
+
+#include <QFileInfo>
+
+#include <utf8string.h>
+
+#include "codecompleter.h"
+
+#include "translationunitisnullexception.h"
+#include "translationunitfilenotexitexception.h"
+#include "translationunitparseerrorexception.h"
+#include "unsavedfiles.h"
+#include "projectpart.h"
+
+namespace CodeModelBackEnd {
+
+class TranslationUnitData
+{
+public:
+ TranslationUnitData(const Utf8String &filePath,
+ const UnsavedFiles &unsavedFiles,
+ const ProjectPart &projectPart);
+ ~TranslationUnitData();
+
+public:
+ time_point lastChangeTimePoint;
+ ProjectPart projectPart;
+ Utf8String filePath;
+ CXTranslationUnit translationUnit = nullptr;
+ CXIndex index = nullptr;
+ UnsavedFiles unsavedFiles;
+};
+
+TranslationUnitData::TranslationUnitData(const Utf8String &filePath,
+ const UnsavedFiles &unsavedFiles,
+ const ProjectPart &projectPart)
+ : lastChangeTimePoint(std::chrono::steady_clock::now()),
+ projectPart(projectPart),
+ filePath(filePath),
+ unsavedFiles(unsavedFiles)
+{
+}
+
+TranslationUnitData::~TranslationUnitData()
+{
+ clang_disposeTranslationUnit(translationUnit);
+ clang_disposeIndex(index);
+}
+
+TranslationUnit::TranslationUnit(const Utf8String &filePath,
+ const UnsavedFiles &unsavedFiles,
+ const ProjectPart &project,
+ FileExistsCheck fileExistsCheck)
+ : d(std::make_shared<TranslationUnitData>(filePath, unsavedFiles, project))
+{
+ if (fileExistsCheck == CheckIfFileExists)
+ checkIfFileExists();
+}
+
+bool TranslationUnit::isNull() const
+{
+ return !d;
+}
+
+void TranslationUnit::reset()
+{
+ d.reset();
+}
+
+CXIndex TranslationUnit::index() const
+{
+ checkIfNull();
+
+ if (!d->index)
+ d->index = clang_createIndex(1, 1);
+
+ return d->index;
+}
+
+CXTranslationUnit TranslationUnit::cxTranslationUnit() const
+{
+ checkIfNull();
+
+ removeOutdatedTranslationUnit();
+
+ createTranslationUnitIfNeeded();
+
+ return d->translationUnit;
+}
+
+const Utf8String &TranslationUnit::filePath() const
+{
+ checkIfNull();
+
+ return d->filePath;
+}
+
+const Utf8String &TranslationUnit::projectPartId() const
+{
+ checkIfNull();
+
+ return d->projectPart.projectPartId();
+}
+
+const time_point &TranslationUnit::lastChangeTimePoint() const
+{
+ return d->lastChangeTimePoint;
+}
+
+void TranslationUnit::checkIfNull() const
+{
+ if (isNull())
+ throw TranslationUnitIsNullException();
+}
+
+void TranslationUnit::checkIfFileExists() const
+{
+ if (!QFileInfo::exists(d->filePath.toString()))
+ throw TranslationUnitFileNotExitsException(d->filePath);
+}
+
+void TranslationUnit::updateLastChangeTimePoint() const
+{
+ d->lastChangeTimePoint = std::chrono::steady_clock::now();
+}
+
+void TranslationUnit::removeOutdatedTranslationUnit() const
+{
+ if (d->projectPart.lastChangeTimePoint() >= d->lastChangeTimePoint) {
+ clang_disposeTranslationUnit(d->translationUnit);
+ d->translationUnit = nullptr;
+ }
+}
+
+void TranslationUnit::createTranslationUnitIfNeeded() const
+{
+ const auto options = CXTranslationUnit_DetailedPreprocessingRecord
+ | CXTranslationUnit_CacheCompletionResults
+ | CXTranslationUnit_PrecompiledPreamble
+ | CXTranslationUnit_SkipFunctionBodies;
+
+ if (!d->translationUnit) {
+ d->translationUnit = CXTranslationUnit();
+ CXErrorCode errorCode = clang_parseTranslationUnit2(index(),
+ d->filePath.constData(),
+ d->projectPart.cxArguments(),
+ d->projectPart.argumentCount(),
+ d->unsavedFiles.cxUnsavedFiles(),
+ d->unsavedFiles.count(),
+ options,
+ &d->translationUnit);
+
+ checkTranslationUnitErrorCode(errorCode);
+
+ updateLastChangeTimePoint();
+ }
+}
+
+void TranslationUnit::checkTranslationUnitErrorCode(CXErrorCode errorCode) const
+{
+ switch (errorCode) {
+ case CXError_Success: break;
+ default: throw TranslationUnitParseErrorException(d->filePath, d->projectPart.projectPartId());
+ }
+}
+
+uint TranslationUnit::unsavedFilesCount() const
+{
+ return d->unsavedFiles.count();
+}
+
+CXUnsavedFile *TranslationUnit::cxUnsavedFiles() const
+{
+ return d->unsavedFiles.cxUnsavedFiles();
+}
+
+TranslationUnit::~TranslationUnit() = default;
+
+TranslationUnit::TranslationUnit(const TranslationUnit &) = default;
+TranslationUnit &TranslationUnit::operator =(const TranslationUnit &) = default;
+
+TranslationUnit::TranslationUnit(TranslationUnit &&other)
+ : d(std::move(other.d))
+{
+}
+
+TranslationUnit &TranslationUnit::operator =(TranslationUnit &&other)
+{
+ d = std::move(other.d);
+
+ return *this;
+}
+
+bool operator ==(const TranslationUnit &first, const TranslationUnit &second)
+{
+ return first.filePath() == second.filePath() && first.projectPartId() == second.projectPartId();
+}
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/translationunit.h b/src/tools/codemodelbackend/ipcsource/translationunit.h
new file mode 100644
index 0000000000..cb939446ce
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunit.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_TRANSLATIONUNIT_H
+#define CODEMODELBACKEND_TRANSLATIONUNIT_H
+
+#include <clang-c/Index.h>
+
+#include <chrono>
+#include <memory>
+
+#include <QtGlobal>
+
+class Utf8String;
+
+namespace CodeModelBackEnd {
+
+class TranslationUnitData;
+class CodeCompleter;
+class UnsavedFiles;
+class ProjectPart;
+
+using time_point = std::chrono::steady_clock::time_point;
+
+class TranslationUnit
+{
+public:
+ enum FileExistsCheck {
+ CheckIfFileExists,
+ DoNotCheckIfFileExists
+ };
+
+ TranslationUnit() = default;
+ TranslationUnit(const Utf8String &filePath,
+ const UnsavedFiles &unsavedFiles,
+ const ProjectPart &projectPart,
+ FileExistsCheck fileExistsCheck = CheckIfFileExists);
+ ~TranslationUnit();
+
+ TranslationUnit(const TranslationUnit &cxTranslationUnit);
+ TranslationUnit &operator =(const TranslationUnit &cxTranslationUnit);
+
+ TranslationUnit(TranslationUnit &&cxTranslationUnit);
+ TranslationUnit &operator =(TranslationUnit &&cxTranslationUnit);
+
+ bool isNull() const;
+
+ void reset();
+
+ CXIndex index() const;
+ CXTranslationUnit cxTranslationUnit() const;
+ CXUnsavedFile * cxUnsavedFiles() const;
+ uint unsavedFilesCount() const;
+
+ const Utf8String &filePath() const;
+ const Utf8String &projectPartId() const;
+
+ const time_point &lastChangeTimePoint() const;
+
+private:
+ void checkIfNull() const;
+ void checkIfFileExists() const;
+ void updateLastChangeTimePoint() const;
+ void removeOutdatedTranslationUnit() const;
+ void createTranslationUnitIfNeeded() const;
+ void checkTranslationUnitErrorCode(CXErrorCode errorCode) const;
+
+private:
+ mutable std::shared_ptr<TranslationUnitData> d;
+};
+
+bool operator ==(const TranslationUnit &first, const TranslationUnit &second);
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_TRANSLATIONUNIT_H
diff --git a/src/tools/codemodelbackend/ipcsource/translationunitdoesnotexistexception.cpp b/src/tools/codemodelbackend/ipcsource/translationunitdoesnotexistexception.cpp
new file mode 100644
index 0000000000..61761283cb
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunitdoesnotexistexception.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "translationunitdoesnotexistexception.h"
+
+namespace CodeModelBackEnd {
+
+TranslationUnitDoesNotExistException::TranslationUnitDoesNotExistException(const FileContainer &fileContainer)
+ : fileContainer_(fileContainer)
+{
+}
+
+TranslationUnitDoesNotExistException::TranslationUnitDoesNotExistException(const Utf8String filePath, const Utf8String projectPartId)
+ : fileContainer_(filePath, projectPartId)
+{
+}
+
+const FileContainer &TranslationUnitDoesNotExistException::fileContainer() const
+{
+ return fileContainer_;
+}
+
+const char *TranslationUnitDoesNotExistException::what() const Q_DECL_NOEXCEPT
+{
+ if (what_.isEmpty())
+ what_ += Utf8StringLiteral("Parse error for file ")
+ + fileContainer_.filePath()
+ + Utf8StringLiteral(" in project ")
+ + fileContainer_.projectPartId()
+ + Utf8StringLiteral("!");
+
+ return what_.constData();
+}
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/translationunitdoesnotexistexception.h b/src/tools/codemodelbackend/ipcsource/translationunitdoesnotexistexception.h
new file mode 100644
index 0000000000..87a5b53c01
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunitdoesnotexistexception.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_TRANSLATIONUNITDONOTEXISTS_H
+#define CODEMODELBACKEND_TRANSLATIONUNITDONOTEXISTS_H
+
+#include <filecontainer.h>
+
+namespace CodeModelBackEnd {
+
+class TranslationUnitDoesNotExistException : public std::exception
+{
+public:
+ TranslationUnitDoesNotExistException(const FileContainer &fileContainer);
+ TranslationUnitDoesNotExistException(const Utf8String filePath, const Utf8String projectPartId);
+
+ const FileContainer &fileContainer() const;
+
+ const char *what() const Q_DECL_NOEXCEPT override;
+
+private:
+ FileContainer fileContainer_;
+ mutable Utf8String what_;
+};
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_TRANSLATIONUNITDONOTEXISTS_H
diff --git a/src/tools/codemodelbackend/ipcsource/translationunitfilenotexitexception.cpp b/src/tools/codemodelbackend/ipcsource/translationunitfilenotexitexception.cpp
new file mode 100644
index 0000000000..29836a22bc
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunitfilenotexitexception.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "translationunitfilenotexitexception.h"
+
+namespace CodeModelBackEnd {
+
+TranslationUnitFileNotExitsException::TranslationUnitFileNotExitsException(const Utf8String &filePath)
+ : filePath_(filePath)
+{
+}
+
+const Utf8String &TranslationUnitFileNotExitsException::filePath() const
+{
+ return filePath_;
+}
+
+const char *TranslationUnitFileNotExitsException::what() const Q_DECL_NOEXCEPT
+{
+ if (what_.isEmpty())
+ what_ += Utf8StringLiteral("File ")
+ + filePath()
+ + Utf8StringLiteral(" in project does not exist!");
+
+ return what_.constData();
+}
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/translationunitfilenotexitexception.h b/src/tools/codemodelbackend/ipcsource/translationunitfilenotexitexception.h
new file mode 100644
index 0000000000..c629f8e86f
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunitfilenotexitexception.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_TRANSLATIONUNITFILENOTEXITS_H
+#define CODEMODELBACKEND_TRANSLATIONUNITFILENOTEXITS_H
+
+#include <utf8string.h>
+
+#include <exception>
+
+namespace CodeModelBackEnd {
+
+class TranslationUnitFileNotExitsException : public std::exception
+{
+public:
+ TranslationUnitFileNotExitsException(const Utf8String &filePath);
+
+ const Utf8String &filePath() const;
+
+ const char *what() const Q_DECL_NOEXCEPT override;
+
+private:
+ Utf8String filePath_;
+ mutable Utf8String what_;
+};
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_TRANSLATIONUNITFILENOTEXITS_H
diff --git a/src/tools/codemodelbackend/ipcsource/translationunitisnullexception.cpp b/src/tools/codemodelbackend/ipcsource/translationunitisnullexception.cpp
new file mode 100644
index 0000000000..3ebb6a796a
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunitisnullexception.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "translationunitisnullexception.h"
+
+namespace CodeModelBackEnd {
+
+const char *TranslationUnitIsNullException::what() const Q_DECL_NOEXCEPT
+{
+ return "Tried to access a null TranslationUnit!";
+}
+
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/translationunitisnullexception.h b/src/tools/codemodelbackend/ipcsource/translationunitisnullexception.h
new file mode 100644
index 0000000000..d1bf67fab7
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunitisnullexception.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_TRANSLATIONUNITISNULLEXCEPTION_H
+#define CODEMODELBACKEND_TRANSLATIONUNITISNULLEXCEPTION_H
+
+#include <QtGlobal>
+
+#include <exception>
+
+namespace CodeModelBackEnd {
+
+class TranslationUnitIsNullException : public std::exception
+{
+public:
+ const char *what() const Q_DECL_NOEXCEPT override;
+};
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_TRANSLATIONUNITISNULLEXCEPTION_H
diff --git a/src/tools/codemodelbackend/ipcsource/translationunitparseerrorexception.cpp b/src/tools/codemodelbackend/ipcsource/translationunitparseerrorexception.cpp
new file mode 100644
index 0000000000..abd79a64ed
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunitparseerrorexception.cpp
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "translationunitparseerrorexception.h"
+
+
+
+namespace CodeModelBackEnd {
+
+TranslationUnitParseErrorException::TranslationUnitParseErrorException(const Utf8String &filePath, const Utf8String &projectPartId)
+ : filePath_(filePath),
+ projectPartId_(projectPartId)
+{
+}
+
+const Utf8String &TranslationUnitParseErrorException::filePath() const
+{
+ return filePath_;
+}
+
+const Utf8String &TranslationUnitParseErrorException::projectPartId() const
+{
+ return projectPartId_;
+}
+
+const char *TranslationUnitParseErrorException::what() const Q_DECL_NOEXCEPT
+{
+ if (what_.isEmpty())
+ what_ += Utf8StringLiteral("Parse error for file ")
+ + filePath()
+ + Utf8StringLiteral(" in project ")
+ + projectPartId()
+ + Utf8StringLiteral("!");
+
+ return what_.constData();
+}
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/translationunitparseerrorexception.h b/src/tools/codemodelbackend/ipcsource/translationunitparseerrorexception.h
new file mode 100644
index 0000000000..0f012244b6
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunitparseerrorexception.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_TRANSLATIONUNITPARSEERROREXCEPTION_H
+#define CODEMODELBACKEND_TRANSLATIONUNITPARSEERROREXCEPTION_H
+
+#include <utf8string.h>
+
+#include <exception>
+
+namespace CodeModelBackEnd {
+
+class TranslationUnitParseErrorException : public std::exception
+{
+public:
+ TranslationUnitParseErrorException(const Utf8String &filePath, const Utf8String &projectPartId);
+
+ const Utf8String &filePath() const;
+ const Utf8String &projectPartId() const;
+
+ const char *what() const Q_DECL_NOEXCEPT override;
+
+private:
+ Utf8String filePath_;
+ Utf8String projectPartId_;
+ mutable Utf8String what_;
+};
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_TRANSLATIONUNITPARSEERROREXCEPTION_H
diff --git a/src/tools/codemodelbackend/ipcsource/translationunits.cpp b/src/tools/codemodelbackend/ipcsource/translationunits.cpp
new file mode 100644
index 0000000000..469ad58611
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunits.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "translationunits.h"
+
+#include <projects.h>
+#include <translationunitdoesnotexistexception.h>
+#include <projectpartsdonotexistexception.h>
+
+namespace CodeModelBackEnd {
+
+bool operator ==(const FileContainer &fileContainer, const TranslationUnit &translationUnit)
+{
+ return fileContainer.filePath() == translationUnit.filePath() && fileContainer.projectPartId() == translationUnit.projectPartId();
+}
+
+bool operator ==(const TranslationUnit &translationUnit, const FileContainer &fileContainer)
+{
+ return fileContainer == translationUnit;
+}
+
+
+TranslationUnits::TranslationUnits(ProjectParts &projects, UnsavedFiles &unsavedFiles)
+ : projects(projects),
+ unsavedFiles(unsavedFiles)
+{
+}
+
+void TranslationUnits::createOrUpdate(const QVector<FileContainer> &fileContainers)
+{
+ for (const FileContainer &fileContainer : fileContainers)
+ createOrUpdateTranslationUnit(fileContainer);
+}
+
+static bool removeFromFileContainer(QVector<FileContainer> &fileContainers, const TranslationUnit &translationUnit)
+{
+ auto position = std::remove(fileContainers.begin(), fileContainers.end(), translationUnit);
+
+ bool entryIsRemoved = position != fileContainers.end();
+
+ fileContainers.erase(position, fileContainers.end());
+
+ return entryIsRemoved;
+}
+
+
+void TranslationUnits::remove(const QVector<FileContainer> &fileContainers)
+{
+ checkIfProjectPartsExists(fileContainers);
+
+ QVector<FileContainer> processedFileContainers = fileContainers;
+
+ auto removeBeginIterator = std::remove_if(translationUnits_.begin(), translationUnits_.end(), [&processedFileContainers] (const TranslationUnit &translationUnit) {
+ return removeFromFileContainer(processedFileContainers, translationUnit);
+ });
+
+ translationUnits_.erase(removeBeginIterator, translationUnits_.end());
+
+ if (!processedFileContainers.isEmpty())
+ throw TranslationUnitDoesNotExistException(processedFileContainers.first());
+
+}
+
+const TranslationUnit &TranslationUnits::translationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const
+{
+ checkIfProjectPartExists(projectPartId);
+
+ auto findIterator = findTranslationUnit(filePath, projectPartId);
+
+ if (findIterator == translationUnits_.end())
+ throw TranslationUnitDoesNotExistException(FileContainer(filePath, projectPartId));
+
+ return *findIterator;
+}
+
+const std::vector<TranslationUnit> &TranslationUnits::translationUnits() const
+{
+ return translationUnits_;
+}
+
+void TranslationUnits::createOrUpdateTranslationUnit(const FileContainer &fileContainer)
+{
+ TranslationUnit::FileExistsCheck checkIfFileExists = fileContainer.hasUnsavedFileContent() ? TranslationUnit::DoNotCheckIfFileExists : TranslationUnit::CheckIfFileExists;
+ auto findIterator = findTranslationUnit(fileContainer);
+ if (findIterator == translationUnits_.end())
+ translationUnits_.push_back(TranslationUnit(fileContainer.filePath(),
+ unsavedFiles,
+ projects.project(fileContainer.projectPartId()),
+ checkIfFileExists));
+}
+
+std::vector<TranslationUnit>::iterator TranslationUnits::findTranslationUnit(const FileContainer &fileContainer)
+{
+ return std::find(translationUnits_.begin(), translationUnits_.end(), fileContainer);
+}
+
+std::vector<TranslationUnit>::const_iterator TranslationUnits::findTranslationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const
+{
+ FileContainer fileContainer(filePath, projectPartId);
+ return std::find(translationUnits_.begin(), translationUnits_.end(), fileContainer);
+}
+
+void TranslationUnits::checkIfProjectPartExists(const Utf8String &projectFileName) const
+{
+ projects.project(projectFileName);
+}
+
+void TranslationUnits::checkIfProjectPartsExists(const QVector<FileContainer> &fileContainers) const
+{
+ Utf8StringVector notExistingProjectParts;
+
+ for (const FileContainer &fileContainer : fileContainers) {
+ if (!projects.hasProjectPart(fileContainer.projectPartId()))
+ notExistingProjectParts.push_back(fileContainer.projectPartId());
+ }
+
+ if (!notExistingProjectParts.isEmpty())
+ throw ProjectPartDoNotExistException(notExistingProjectParts);
+
+}
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/translationunits.h b/src/tools/codemodelbackend/ipcsource/translationunits.h
new file mode 100644
index 0000000000..105ec0052f
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/translationunits.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_TRANSLATIONUNITS_H
+#define CODEMODELBACKEND_TRANSLATIONUNITS_H
+
+#include <filecontainer.h>
+#include <QVector>
+
+#include <vector>
+
+#include "translationunit.h"
+
+namespace CodeModelBackEnd {
+
+class ProjectParts;
+class UnsavedFiles;
+
+class TranslationUnits
+{
+public:
+ TranslationUnits(ProjectParts &projects, UnsavedFiles &unsavedFiles);
+
+ void createOrUpdate(const QVector<FileContainer> &fileContainers);
+ void remove(const QVector<FileContainer> &fileContainers);
+
+ const TranslationUnit &translationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const;
+
+ const std::vector<TranslationUnit> &translationUnits() const;
+
+private:
+ void createOrUpdateTranslationUnit(const FileContainer &fileContainer);
+ std::vector<TranslationUnit>::iterator findTranslationUnit(const FileContainer &fileContainer);
+ std::vector<TranslationUnit>::const_iterator findTranslationUnit(const Utf8String &filePath, const Utf8String &projectPartId) const;
+ void checkIfProjectPartExists(const Utf8String &projectFileName) const;
+ void checkIfProjectPartsExists(const QVector<FileContainer> &fileContainers) const;
+
+
+private:
+ std::vector<TranslationUnit> translationUnits_;
+ ProjectParts &projects;
+ UnsavedFiles &unsavedFiles;
+};
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_TRANSLATIONUNITS_H
diff --git a/src/tools/codemodelbackend/ipcsource/unsavedfiles.cpp b/src/tools/codemodelbackend/ipcsource/unsavedfiles.cpp
new file mode 100644
index 0000000000..e3fddc4527
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/unsavedfiles.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "unsavedfiles.h"
+
+
+#include <cstring>
+
+namespace CodeModelBackEnd {
+
+class UnsavedFilesData
+{
+public:
+ UnsavedFilesData();
+ ~UnsavedFilesData();
+
+public:
+ time_point lastChangeTimePoint;
+ std::vector<CXUnsavedFile> cxUnsavedFiles;
+};
+
+UnsavedFilesData::UnsavedFilesData()
+ : lastChangeTimePoint(std::chrono::steady_clock::now())
+{
+}
+
+UnsavedFilesData::~UnsavedFilesData()
+{
+ for (const CXUnsavedFile &cxUnsavedFile : cxUnsavedFiles)
+ UnsavedFiles::deleteCXUnsavedFile(cxUnsavedFile);
+
+ cxUnsavedFiles.clear();
+}
+
+UnsavedFiles::UnsavedFiles()
+ : d(std::make_shared<UnsavedFilesData>())
+{
+}
+
+UnsavedFiles::~UnsavedFiles() = default;
+
+UnsavedFiles::UnsavedFiles(const UnsavedFiles &) = default;
+UnsavedFiles &UnsavedFiles::operator =(const UnsavedFiles &) = default;
+
+UnsavedFiles::UnsavedFiles(UnsavedFiles &&other)
+ : d(std::move(other.d))
+{
+}
+
+UnsavedFiles &UnsavedFiles::operator =(UnsavedFiles &&other)
+{
+ d = std::move(other.d);
+
+ return *this;
+}
+
+void UnsavedFiles::createOrUpdate(const QVector<FileContainer> &fileContainers)
+{
+ for (const FileContainer &fileContainer : fileContainers)
+ updateCXUnsavedFileWithFileContainer(fileContainer);
+
+ updateLastChangeTimePoint();
+}
+
+void UnsavedFiles::remove(const QVector<FileContainer> &fileContainers)
+{
+ for (const FileContainer &fileContainer : fileContainers)
+ removeCXUnsavedFile(fileContainer);
+
+ updateLastChangeTimePoint();
+}
+
+void UnsavedFiles::clear()
+{
+ for (const CXUnsavedFile &cxUnsavedFile : d->cxUnsavedFiles)
+ deleteCXUnsavedFile(cxUnsavedFile);
+
+ d->cxUnsavedFiles.clear();
+ updateLastChangeTimePoint();
+}
+
+int UnsavedFiles::count() const
+{
+ return d->cxUnsavedFiles.size();
+}
+
+CXUnsavedFile *UnsavedFiles::cxUnsavedFiles() const
+{
+ return d->cxUnsavedFiles.data();
+}
+
+const std::vector<CXUnsavedFile> &UnsavedFiles::cxUnsavedFileVector() const
+{
+ return d->cxUnsavedFiles;
+}
+
+const time_point &UnsavedFiles::lastChangeTimePoint() const
+{
+ return d->lastChangeTimePoint;
+}
+
+CXUnsavedFile UnsavedFiles::createCxUnsavedFile(const Utf8String &filePath, const Utf8String &fileContent)
+{
+ char *cxUnsavedFilePath = new char[filePath.byteSize() + 1];
+ char *cxUnsavedFileContent = new char[fileContent.byteSize() + 1];
+
+ std::memcpy(cxUnsavedFilePath, filePath.constData(), filePath.byteSize() + 1);
+ std::memcpy(cxUnsavedFileContent, fileContent.constData(), fileContent.byteSize() + 1);
+
+ return CXUnsavedFile { cxUnsavedFilePath, cxUnsavedFileContent, ulong(fileContent.byteSize())};
+}
+
+void UnsavedFiles::deleteCXUnsavedFile(const CXUnsavedFile &cxUnsavedFile)
+{
+ delete [] cxUnsavedFile.Contents;
+ delete [] cxUnsavedFile.Filename;
+}
+
+void UnsavedFiles::updateCXUnsavedFileWithFileContainer(const FileContainer &fileContainer)
+{
+ if (fileContainer.hasUnsavedFileContent()) {
+ addOrUpdateCXUnsavedFile(fileContainer);
+ } else {
+ removeCXUnsavedFile(fileContainer);
+ }
+}
+
+void UnsavedFiles::removeCXUnsavedFile(const FileContainer &fileContainer)
+{
+ const Utf8String filePath = fileContainer.filePath();
+ auto removeBeginIterator = std::remove_if(d->cxUnsavedFiles.begin(),
+ d->cxUnsavedFiles.end(),
+ [filePath] (const CXUnsavedFile &cxUnsavedFile) { return filePath == cxUnsavedFile.Filename; });
+
+ std::for_each(removeBeginIterator, d->cxUnsavedFiles.end(), UnsavedFiles::deleteCXUnsavedFile);
+ d->cxUnsavedFiles.erase( removeBeginIterator, d->cxUnsavedFiles.end());
+}
+
+void UnsavedFiles::addOrUpdateCXUnsavedFile(const FileContainer &fileContainer)
+{
+ const Utf8String filePath = fileContainer.filePath();
+ const Utf8String fileContent = fileContainer.unsavedFileContent();
+ auto isSameFile = [filePath] (const CXUnsavedFile &cxUnsavedFile) { return filePath == cxUnsavedFile.Filename; };
+
+ auto cxUnsavedFileIterator = std::find_if(d->cxUnsavedFiles.begin(), d->cxUnsavedFiles.end(), isSameFile);
+ if (cxUnsavedFileIterator == d->cxUnsavedFiles.end())
+ d->cxUnsavedFiles.push_back(createCxUnsavedFile(filePath, fileContent));
+ else {
+ deleteCXUnsavedFile(*cxUnsavedFileIterator);
+ *cxUnsavedFileIterator = createCxUnsavedFile(filePath, fileContent);
+ }
+}
+
+void UnsavedFiles::updateLastChangeTimePoint()
+{
+ d->lastChangeTimePoint = std::chrono::steady_clock::now();
+}
+
+
+} // namespace CodeModelBackEnd
+
diff --git a/src/tools/codemodelbackend/ipcsource/unsavedfiles.h b/src/tools/codemodelbackend/ipcsource/unsavedfiles.h
new file mode 100644
index 0000000000..c4652d8319
--- /dev/null
+++ b/src/tools/codemodelbackend/ipcsource/unsavedfiles.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef CODEMODELBACKEND_UNSAVEDFILES_H
+#define CODEMODELBACKEND_UNSAVEDFILES_H
+
+#include <filecontainer.h>
+
+#include <chrono>
+#include <vector>
+#include <memory>
+
+#include <QVector>
+
+#include <clang-c/Index.h>
+
+namespace CodeModelBackEnd {
+
+using time_point = std::chrono::steady_clock::time_point;
+
+class UnsavedFilesData;
+
+class UnsavedFiles
+{
+ friend class UnsavedFilesData;
+public:
+ UnsavedFiles();
+ ~UnsavedFiles();
+
+ UnsavedFiles(const UnsavedFiles &unsavedFiles);
+ UnsavedFiles &operator =(const UnsavedFiles &unsavedFiles);
+
+ UnsavedFiles(UnsavedFiles &&unsavedFiles);
+ UnsavedFiles &operator =(UnsavedFiles &&unsavedFiles);
+
+ void createOrUpdate(const QVector<FileContainer> &fileContainers);
+ void remove(const QVector<FileContainer> &fileContainers);
+ void clear();
+
+ int count() const;
+
+ CXUnsavedFile *cxUnsavedFiles() const;
+ const std::vector<CXUnsavedFile> &cxUnsavedFileVector() const;
+
+ const time_point &lastChangeTimePoint() const;
+
+private:
+ CXUnsavedFile createCxUnsavedFile(const Utf8String &filePath, const Utf8String &fileContent);
+ static void deleteCXUnsavedFile(const CXUnsavedFile &cxUnsavedFile);
+ void updateCXUnsavedFileWithFileContainer(const FileContainer &fileContainer);
+ void removeCXUnsavedFile(const FileContainer &fileContainer);
+ void addOrUpdateCXUnsavedFile(const FileContainer &fileContainer);
+ void updateLastChangeTimePoint();
+
+private:
+ mutable std::shared_ptr<UnsavedFilesData> d;
+};
+
+} // namespace CodeModelBackEnd
+
+#endif // CODEMODELBACKEND_UNSAVEDFILES_H
diff --git a/src/tools/codemodelbackend/unittests/clang/clang.pro b/src/tools/codemodelbackend/unittests/clang/clang.pro
new file mode 100644
index 0000000000..e682dbb8c9
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/clang/clang.pro
@@ -0,0 +1,26 @@
+QT += core network testlib
+QT -= gui
+
+TEMPLATE = app
+
+CONFIG += console c++14 testcase
+CONFIG -= app_bundle
+
+TARGET = testlib
+
+include(../../clang.pri)
+include(../../clangsource/codemodelbackendclang-source.pri)
+
+
+LIBS += -L$$OUT_PWD/../codemodelbackendipc/lib/qtcreator -lCodemodelbackendipc
+
+
+SOURCES += tst_clang.cpp
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
+
+INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/codemodelbackendipc/source
+
+HEADERS += \
+ foo.h
+
+DEFINES += TEST_BASE_DIRECTORY=\\\"$$PWD\\\"
diff --git a/src/tools/codemodelbackend/unittests/clang/foo.h b/src/tools/codemodelbackend/unittests/clang/foo.h
new file mode 100644
index 0000000000..ae52108bf1
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/clang/foo.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef FOO_H
+#define FOO_H
+
+void foo(int newValue)
+{
+ new
+}
+
+#endif // FOO_H
+
diff --git a/src/tools/codemodelbackend/unittests/clang/tst_clang.cpp b/src/tools/codemodelbackend/unittests/clang/tst_clang.cpp
new file mode 100644
index 0000000000..387a06cd52
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/clang/tst_clang.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include <QString>
+#include <QtTest>
+
+#include <translationunit.h>
+
+static const char fooHeaderFile[] = TEST_BASE_DIRECTORY "/foo.h";
+
+class ClangTest : public QObject
+{
+ Q_OBJECT
+
+public:
+ ClangTest();
+
+private Q_SLOTS:
+ void init();
+ void completeCode();
+
+private:
+ CodeModelBackEnd::TranslationUnit unit;
+
+};
+
+ClangTest::ClangTest()
+{
+
+}
+
+void ClangTest::init()
+{
+ unit = CodeModelBackEnd::TranslationUnit(fooHeaderFile);
+ unit.parse();
+
+ QVERIFY(unit.isLoaded());
+}
+
+void ClangTest::completeCode()
+{
+ CodeModelBackEnd::ScopedCXCodeCompleteResults results;
+
+ unit.completeCodeAt(36, 7, results);
+
+ QCOMPARE(results.size(), unsigned(361));
+}
+
+QTEST_APPLESS_MAIN(ClangTest)
+
+#include "tst_clang.moc"
diff --git a/src/tools/codemodelbackend/unittests/codemodelbackendipc/codemodelbackendipc.pro b/src/tools/codemodelbackend/unittests/codemodelbackendipc/codemodelbackendipc.pro
new file mode 100644
index 0000000000..2f09b33596
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/codemodelbackendipc/codemodelbackendipc.pro
@@ -0,0 +1,5 @@
+unix:QMAKE_CXXFLAGS_DEBUG += -O2
+win32:QMAKE_CXXFLAGS_DEBUG += -O2
+
+include(../../../../qtcreatorlibrary.pri)
+include(../../../../libs/codemodelbackendipc/codemodelbackendipc-lib.pri)
diff --git a/src/tools/codemodelbackend/unittests/codemodelbackendipc/codemodelbackendipc_dependencies.pri b/src/tools/codemodelbackend/unittests/codemodelbackendipc/codemodelbackendipc_dependencies.pri
new file mode 100644
index 0000000000..295fcc7e35
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/codemodelbackendipc/codemodelbackendipc_dependencies.pri
@@ -0,0 +1,2 @@
+QTC_LIB_NAME = Codemodelbackendipc
+INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/codemodelbackendipc/source
diff --git a/src/tools/codemodelbackend/unittests/codemodelbackendprocess/codemodelbackendprocess.pro b/src/tools/codemodelbackend/unittests/codemodelbackendprocess/codemodelbackendprocess.pro
new file mode 100644
index 0000000000..a57e08eafc
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/codemodelbackendprocess/codemodelbackendprocess.pro
@@ -0,0 +1 @@
+include(../../codemodelbackend.pri)
diff --git a/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/clientdummy.cpp b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/clientdummy.cpp
new file mode 100644
index 0000000000..f7b58fe5f0
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/clientdummy.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "clientdummy.h"
+
+void ClientDummy::clear()
+{
+ codeCompletedCommand = CodeModelBackEnd::CodeCompletedCommand ();
+}
+
+void ClientDummy::alive()
+{
+}
+
+void ClientDummy::echo(const CodeModelBackEnd::EchoCommand &command)
+{
+}
+
+void ClientDummy::codeCompleted(const CodeModelBackEnd::CodeCompletedCommand &command)
+{
+ codeCompletedCommand = command;
+
+ emit newCodeCompleted();
+}
diff --git a/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/clientdummy.h b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/clientdummy.h
new file mode 100644
index 0000000000..5571a8c46b
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/clientdummy.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+
+#ifndef CLIENTDUMMY_H
+#define CLIENTDUMMY_H
+
+#include "ipcclientinterface.h"
+
+
+#include <QVariant>
+#include <QObject>
+
+#include <QObject>
+
+#include <cmbechocommand.h>
+#include <cmbcodecompletedcommand.h>
+
+class ClientDummy : public QObject, public CodeModelBackEnd::IpcClientInterface
+{
+ Q_OBJECT
+
+public:
+ void clear();
+
+ void alive() override;
+ void echo(const CodeModelBackEnd::EchoCommand &command) override;
+ void codeCompleted(const CodeModelBackEnd::CodeCompletedCommand &command) override;
+
+ CodeModelBackEnd::CodeCompletedCommand codeCompletedCommand;
+
+signals:
+ void newCodeCompleted();
+};
+
+#endif // CLIENTDUMMY_H
diff --git a/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/codemodelbackendprocesstest.pro b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/codemodelbackendprocesstest.pro
new file mode 100644
index 0000000000..0d625c6f50
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/codemodelbackendprocesstest.pro
@@ -0,0 +1,22 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2015-01-14T17:00:27
+#
+#-------------------------------------------------
+
+
+TARGET = tst_codemodelbackendprocess
+
+include(../codemodelbackendprocesstestcommon.pri)
+
+SOURCES += tst_codemodelbackendprocess.cpp \
+ clientdummy.cpp
+DEFINES += SRCDIR=\\\"$$PWD/\\\"
+
+INCLUDEPATH *= $$IDE_SOURCE_TREE/src/libs/codemodelbackendipc/source
+
+HEADERS += \
+ clientdummy.h \
+ foo.h
+
+DEFINES += TEST_BASE_DIRECTORY=\\\"$$PWD\\\"
diff --git a/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/foo.h b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/foo.h
new file mode 100644
index 0000000000..6851b929b3
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/foo.h
@@ -0,0 +1,40 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#ifndef FOO_H
+#define FOO_H
+
+void foo(int newValue)
+{
+
+}
+
+#endif // FOO_H
+
diff --git a/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/tst_codemodelbackendprocess.cpp b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/tst_codemodelbackendprocess.cpp
new file mode 100644
index 0000000000..09757c48b7
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstest/tst_codemodelbackendprocess.cpp
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia. For licensing terms and
+** conditions see http://www.qt.io/licensing. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include <QString>
+#include <QtTest>
+
+#include <connectionclient.h>
+#include <clientdummy.h>
+#include <cmbcommands.h>
+#include <filecontainer.h>
+
+#include <cmbcompletecodecommand.h>
+#include <cmbcodecompletedcommand.h>
+
+static const char fooHeaderFile[] = TEST_BASE_DIRECTORY "/foo.h";
+
+class CodeModelBackendProcessTest : public QObject
+{
+ Q_OBJECT
+
+public:
+ CodeModelBackendProcessTest();
+
+private Q_SLOTS:
+ void init();
+ void cleanup();
+ void completeCode();
+
+private:
+ void registerFiles();
+
+private:
+ ClientDummy clientDummy;
+ CodeModelBackEnd::ConnectionClient client;
+};
+
+CodeModelBackendProcessTest::CodeModelBackendProcessTest()
+ : client(&clientDummy)
+{
+ CodeModelBackEnd::Commands::registerCommands();
+ client.setProcessPath(QLatin1String(CODEMODELBACKENDPROCESSPATH));
+}
+
+void CodeModelBackendProcessTest::init()
+{
+ client.startProcess();
+ client.connectToServer();
+
+}
+
+void CodeModelBackendProcessTest::cleanup()
+{
+ client.disconnectFromServer();
+ client.sendEndCommand();
+}
+
+void CodeModelBackendProcessTest::completeCode()
+{
+ QSignalSpy clientSpy(&clientDummy, &ClientDummy::newCodeCompleted);
+ registerFiles();
+
+ client.sendCompleteCodeCommand(fooHeaderFile, 36, 0, "");
+
+ QVERIFY(clientSpy.wait(3000));
+}
+
+void CodeModelBackendProcessTest::registerFiles()
+{
+ CodeModelBackEnd::FileContainer fileContainer(fooHeaderFile);
+ QVector<CodeModelBackEnd::FileContainer> fileContainers({fileContainer});
+
+ client.sendRegisterFilesForCodeCompletionCommand(fileContainers);
+}
+
+QTEST_MAIN(CodeModelBackendProcessTest)
+
+#include "tst_codemodelbackendprocess.moc"
diff --git a/src/tools/codemodelbackend/unittests/codemodelbackendprocesstestcommon.pri b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstestcommon.pri
new file mode 100644
index 0000000000..a971689a1c
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/codemodelbackendprocesstestcommon.pri
@@ -0,0 +1,23 @@
+QT += core network testlib
+QT -= gui
+
+TEMPLATE = app
+
+CONFIG += console c++14 testcase
+CONFIG -= app_bundle
+
+include(../../../../qtcreator.pri)
+
+LIBS += -L$$OUT_PWD/../codemodelbackendipc/lib/qtcreator -lCodemodelbackendipc
+unix:LIBS += -ldl
+
+INCLUDEPATH += $$PWD/../source
+
+QMAKE_CXXFLAGS -= -O2
+#unix:QMAKE_CXXFLAGS += -fprofile-arcs -ftest-coverage -O0
+#unix:QMAKE_LDFLAGS += -fprofile-arcs -ftest-coverage
+#unix:LIBS += -lgcov
+
+DEFINES += QT_NO_CAST_FROM_ASCII
+DEFINES += CODEMODELBACKENDPROCESS_TESTS
+DEFINES += CODEMODELBACKENDPROCESSPATH=\\\"$$OUT_PWD/../codemodelbackendprocess/codemodelbackend\\\"
diff --git a/src/tools/codemodelbackend/unittests/codemodelbackendprocessunittests.pro b/src/tools/codemodelbackend/unittests/codemodelbackendprocessunittests.pro
new file mode 100644
index 0000000000..ccba078fcc
--- /dev/null
+++ b/src/tools/codemodelbackend/unittests/codemodelbackendprocessunittests.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+SUBDIRS = codemodelbackendipc \
+ codemodelbackendprocess \
+ codemodelbackendprocesstest \
+ clang
+
+codemodelbackendprocess.depends = codemodelbackendipc
+codemodelbackendprocesstest.depends = codemodelbackendprocess codemodelbackendipc clang