aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarco Bubke <marco.bubke@qt.io>2018-12-17 12:06:57 +0100
committerMarco Bubke <marco.bubke@qt.io>2019-01-21 15:27:10 +0000
commitdd366b68dea11eebb0b1c53f3cff1902ce2bfefa (patch)
treeb919ffd70c5e3677244d2475381f6fb8defdd3eb
parenta78e3e5dd5f882a28a3152f2e63ae986a9f2a8c5 (diff)
PchManager: Split pch tasks in project and system pch tasks
Like you can see in the task numbers this patch is touching many different areas. So I will only touch the main parts. It is using a clang action instead of an extra process which will be enabling the handling of generated files in PCHs. The flags from the project part are now not anymore transformed in a command line but they are saved in the container semantically aware so that they can later be merged. Most of this patch is simply polishing of other patches. Task-number: QTCREATORBUG-21346 Task-number: QTCREATORBUG-21380 Task-number: QTCREATORBUG-21382 Task-number: QTCREATORBUG-21383 Task-number: QTCREATORBUG-21693 Task-number: QTCREATORBUG-21778 Change-Id: I9b0c02d8149b554254e819448fbc61eeaa5b7494 Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
-rw-r--r--src/libs/clangsupport/clangsupport-lib.pri10
-rw-r--r--src/libs/clangsupport/commandlinebuilder.h258
-rw-r--r--src/libs/clangsupport/filepath.h8
-rw-r--r--src/libs/clangsupport/filepathview.h1
-rw-r--r--src/libs/clangsupport/includesearchpath.h102
-rw-r--r--src/libs/clangsupport/progresscounter.h18
-rw-r--r--src/libs/clangsupport/projectpartcontainer.cpp (renamed from src/libs/clangsupport/projectpartcontainerv2.cpp)7
-rw-r--r--src/libs/clangsupport/projectpartcontainer.h164
-rw-r--r--src/libs/clangsupport/projectpartcontainerv2.h125
-rw-r--r--src/libs/clangsupport/projectpartpch.h8
-rw-r--r--src/libs/clangsupport/refactoringdatabaseinitializer.h3
-rw-r--r--src/libs/clangsupport/removeprojectpartsmessage.h2
-rw-r--r--src/libs/clangsupport/updateprojectpartsmessage.h16
-rw-r--r--src/libs/utils/cpplanguage_details.h12
-rw-r--r--src/plugins/clangpchmanager/projectupdater.cpp119
-rw-r--r--src/plugins/clangpchmanager/projectupdater.h26
-rw-r--r--src/plugins/clangpchmanager/qtcreatorprojectupdater.h3
-rw-r--r--src/plugins/clangrefactoring/refactoringprojectupdater.cpp2
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.cpp6
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.h1
-rw-r--r--src/plugins/cpptools/cppprojectinfogenerator.cpp1
-rw-r--r--src/plugins/cpptools/projectpart.h3
-rw-r--r--src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp73
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp2
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h2
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h4
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp8
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependencycollector.h2
-rw-r--r--src/tools/clangpchmanagerbackend/source/builddependencygeneratorinterface.h4
-rw-r--r--src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri9
-rw-r--r--src/tools/clangpchmanagerbackend/source/environment.h1
-rw-r--r--src/tools/clangpchmanagerbackend/source/generatepchactionfactory.h41
-rw-r--r--src/tools/clangpchmanagerbackend/source/modifiedtimechecker.h149
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.cpp339
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreator.h72
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h6
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp23
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchmanagerserver.h8
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtask.h47
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp32
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtaskgenerator.h9
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtaskgeneratorinterface.h (renamed from src/tools/clangpchmanagerbackend/source/projectpartqueueinterface.h)13
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp41
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp8
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtasksmerger.h3
-rw-r--r--src/tools/clangpchmanagerbackend/source/pchtasksmergerinterface.h3
-rw-r--r--src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h34
-rw-r--r--src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h15
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartqueue.cpp137
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartqueue.h74
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectparts.cpp24
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectparts.h12
-rw-r--r--src/tools/clangpchmanagerbackend/source/projectpartsinterface.h6
-rw-r--r--src/tools/clangpchmanagerbackend/source/sourceentry.h72
-rw-r--r--src/tools/clangpchmanagerbackend/source/taskscheduler.h27
-rw-r--r--src/tools/clangpchmanagerbackend/source/toolchainargumentscache.h187
-rw-r--r--src/tools/clangpchmanagerbackend/source/usedmacrofilter.h10
-rw-r--r--src/tools/clangrefactoringbackend/source/clangtool.cpp15
-rw-r--r--src/tools/clangrefactoringbackend/source/clangtool.h1
-rw-r--r--src/tools/clangrefactoringbackend/source/projectpartartefact.cpp52
-rw-r--r--src/tools/clangrefactoringbackend/source/projectpartartefact.h36
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexer.cpp85
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexer.h19
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexing.cpp2
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexing.h22
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolindexinginterface.h4
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolstorage.h87
-rw-r--r--src/tools/clangrefactoringbackend/source/symbolstorageinterface.h25
-rw-r--r--tests/unit/unittest/builddependenciesprovider-test.cpp34
-rw-r--r--tests/unit/unittest/builddependencycollector-test.cpp38
-rw-r--r--tests/unit/unittest/commandlinebuilder-test.cpp481
-rw-r--r--tests/unit/unittest/google-using-declarations.h1
-rw-r--r--tests/unit/unittest/googletest.h1
-rw-r--r--tests/unit/unittest/gtest-creator-printing.cpp163
-rw-r--r--tests/unit/unittest/gtest-creator-printing.h16
-rw-r--r--tests/unit/unittest/mockbuilddependenciesprovider.h2
-rw-r--r--tests/unit/unittest/mockbuilddependencygenerator.h2
-rw-r--r--tests/unit/unittest/mockpchcreator.h9
-rw-r--r--tests/unit/unittest/mockpchtaskgenerator.h46
-rw-r--r--tests/unit/unittest/mockpchtasksmerger.h12
-rw-r--r--tests/unit/unittest/mockprecompiledheaderstorage.h9
-rw-r--r--tests/unit/unittest/mockprojectpartqueue.h4
-rw-r--r--tests/unit/unittest/mockprojectparts.h6
-rw-r--r--tests/unit/unittest/mocksqlitereadstatement.cpp11
-rw-r--r--tests/unit/unittest/mocksqlitereadstatement.h11
-rw-r--r--tests/unit/unittest/mocksqlitewritestatement.h6
-rw-r--r--tests/unit/unittest/mocksymbolindexing.h4
-rw-r--r--tests/unit/unittest/mocksymbolstorage.h5
-rw-r--r--tests/unit/unittest/modifiedtimechecker-test.cpp109
-rw-r--r--tests/unit/unittest/pchcreator-test.cpp258
-rw-r--r--tests/unit/unittest/pchmanagerclient-test.cpp4
-rw-r--r--tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp21
-rw-r--r--tests/unit/unittest/pchmanagerserver-test.cpp74
-rw-r--r--tests/unit/unittest/pchtaskgenerator-test.cpp122
-rw-r--r--tests/unit/unittest/pchtaskqueue-test.cpp102
-rw-r--r--tests/unit/unittest/pchtasksmerger-test.cpp59
-rw-r--r--tests/unit/unittest/precompiledheaderstorage-test.cpp50
-rw-r--r--tests/unit/unittest/progresscounter-test.cpp28
-rw-r--r--tests/unit/unittest/projectpartartefact-test.cpp62
-rw-r--r--tests/unit/unittest/projectpartqueue-test.cpp183
-rw-r--r--tests/unit/unittest/projectparts-test.cpp55
-rw-r--r--tests/unit/unittest/projectupdater-test.cpp127
-rw-r--r--tests/unit/unittest/refactoringclientserverinprocess-test.cpp15
-rw-r--r--tests/unit/unittest/refactoringdatabaseinitializer-test.cpp4
-rw-r--r--tests/unit/unittest/refactoringprojectupdater-test.cpp2
-rw-r--r--tests/unit/unittest/refactoringserver-test.cpp30
-rw-r--r--tests/unit/unittest/symbolindexer-test.cpp283
-rw-r--r--tests/unit/unittest/symbolindexing-test.cpp16
-rw-r--r--tests/unit/unittest/symbolstorage-test.cpp75
-rw-r--r--tests/unit/unittest/taskscheduler-test.cpp34
-rw-r--r--tests/unit/unittest/testenvironment.h5
-rw-r--r--tests/unit/unittest/toolchainargumentscache-test.cpp199
-rw-r--r--tests/unit/unittest/unittest.pro9
-rw-r--r--tests/unit/unittest/usedmacrofilter-test.cpp14
114 files changed, 3748 insertions, 1793 deletions
diff --git a/src/libs/clangsupport/clangsupport-lib.pri b/src/libs/clangsupport/clangsupport-lib.pri
index 03713650ad..221ccfd001 100644
--- a/src/libs/clangsupport/clangsupport-lib.pri
+++ b/src/libs/clangsupport/clangsupport-lib.pri
@@ -44,7 +44,6 @@ SOURCES += \
$$PWD/pchmanagerserverinterface.cpp \
$$PWD/pchmanagerserverproxy.cpp \
$$PWD/precompiledheadersupdatedmessage.cpp \
- $$PWD/projectpartcontainerv2.cpp \
$$PWD/projectpartpch.cpp \
$$PWD/readmessageblock.cpp \
$$PWD/refactoringclientinterface.cpp \
@@ -87,7 +86,8 @@ SOURCES += \
$$PWD/baseserverproxy.cpp \
$$PWD/updategeneratedfilesmessage.cpp \
$$PWD/removegeneratedfilesmessage.cpp \
- $$PWD/generatedfiles.cpp
+ $$PWD/generatedfiles.cpp \
+ $$PWD/projectpartcontainer.cpp
HEADERS += \
$$PWD/cancelmessage.h \
@@ -138,7 +138,6 @@ HEADERS += \
$$PWD/pchmanagerserverinterface.h \
$$PWD/pchmanagerserverproxy.h \
$$PWD/precompiledheadersupdatedmessage.h \
- $$PWD/projectpartcontainerv2.h \
$$PWD/projectpartpch.h \
$$PWD/readmessageblock.h \
$$PWD/refactoringclientinterface.h \
@@ -205,6 +204,9 @@ HEADERS += \
$$PWD/generatedfiles.h \
$$PWD/generatedfilesinterface.h \
$$PWD/progressmessage.h \
- $$PWD/progresscounter.h
+ $$PWD/progresscounter.h \
+ $$PWD/includesearchpath.h \
+ $$PWD/commandlinebuilder.h \
+ $$PWD/projectpartcontainer.h
contains(QT_CONFIG, reduce_exports):CONFIG += hide_symbols
diff --git a/src/libs/clangsupport/commandlinebuilder.h b/src/libs/clangsupport/commandlinebuilder.h
new file mode 100644
index 0000000000..af9c0f1baf
--- /dev/null
+++ b/src/libs/clangsupport/commandlinebuilder.h
@@ -0,0 +1,258 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "filepathview.h"
+
+#include <compilermacro.h>
+#include <includesearchpath.h>
+
+#include <utils/smallstringvector.h>
+#include <utils/cpplanguage_details.h>
+
+namespace ClangBackEnd {
+
+template<typename ProjectInfo, typename OutputContainer = std::vector<std::string>>
+class CommandLineBuilder
+{
+public:
+ CommandLineBuilder(const ProjectInfo &projectInfo,
+ const Utils::SmallStringVector &toolChainArguments = {},
+ FilePathView sourcePath = {},
+ FilePathView outputPath = {},
+ FilePathView includePchPath = {})
+ {
+ commandLine.reserve(128);
+
+ addCompiler(projectInfo.language);
+ addToolChainArguments(toolChainArguments);
+ addLanguage(projectInfo);
+ addLanguageVersion(projectInfo);
+ addNoStdIncAndNoStdLibInc();
+ addProjectIncludeSearchPaths(
+ sortedIncludeSearchPaths(projectInfo.projectIncludeSearchPaths));
+ addSystemAndBuiltInIncludeSearchPaths(
+ sortedIncludeSearchPaths(projectInfo.systemIncludeSearchPaths));
+ addIncludePchPath(includePchPath);
+ addOutputPath(outputPath);
+ addSourcePath(sourcePath);
+ }
+
+ void addCompiler(Utils::Language language)
+ {
+ if (language == Utils::Language::Cxx)
+ commandLine.emplace_back("clang++");
+ else
+ commandLine.emplace_back("clang");
+ }
+
+ void addToolChainArguments(const Utils::SmallStringVector &toolChainArguments)
+ {
+ for (Utils::SmallStringView argument : toolChainArguments)
+ commandLine.emplace_back(argument);
+ }
+
+ static const char *language(const ProjectInfo &projectInfo)
+ {
+ switch (projectInfo.language) {
+ case Utils::Language::C:
+ if (projectInfo.languageExtension && Utils::LanguageExtension::ObjectiveC)
+ return "objective-c-header";
+
+ return "c-header";
+ case Utils::Language::Cxx:
+ if (projectInfo.languageExtension && Utils::LanguageExtension::ObjectiveC)
+ return "objective-c++-header";
+ }
+
+ return "c++-header";
+ }
+
+ void addLanguage(const ProjectInfo &projectInfo)
+ {
+ commandLine.emplace_back("-x");
+ commandLine.emplace_back(language(projectInfo));
+ }
+
+ const char *standardLanguageVersion(Utils::LanguageVersion languageVersion)
+ {
+ switch (languageVersion) {
+ case Utils::LanguageVersion::C89:
+ return "-std=c89";
+ case Utils::LanguageVersion::C99:
+ return "-std=c99";
+ case Utils::LanguageVersion::C11:
+ return "-std=c11";
+ case Utils::LanguageVersion::C18:
+ return "-std=c18";
+ case Utils::LanguageVersion::CXX98:
+ return "-std=c++98";
+ case Utils::LanguageVersion::CXX03:
+ return "-std=c++03";
+ case Utils::LanguageVersion::CXX11:
+ return "-std=c++11";
+ case Utils::LanguageVersion::CXX14:
+ return "-std=c++14";
+ case Utils::LanguageVersion::CXX17:
+ return "-std=c++17";
+ case Utils::LanguageVersion::CXX2a:
+ return "-std=c++2a";
+ }
+
+ return "-std=c++2a";
+ }
+
+ const char *gnuLanguageVersion(Utils::LanguageVersion languageVersion)
+ {
+ switch (languageVersion) {
+ case Utils::LanguageVersion::C89:
+ return "-std=gnu89";
+ case Utils::LanguageVersion::C99:
+ return "-std=gnu99";
+ case Utils::LanguageVersion::C11:
+ return "-std=gnu11";
+ case Utils::LanguageVersion::C18:
+ return "-std=gnu18";
+ case Utils::LanguageVersion::CXX98:
+ return "-std=gnu++98";
+ case Utils::LanguageVersion::CXX03:
+ return "-std=gnu++03";
+ case Utils::LanguageVersion::CXX11:
+ return "-std=gnu++11";
+ case Utils::LanguageVersion::CXX14:
+ return "-std=gnu++14";
+ case Utils::LanguageVersion::CXX17:
+ return "-std=gnu++17";
+ case Utils::LanguageVersion::CXX2a:
+ return "-std=gnu++2a";
+ }
+
+ return "-std=gnu++2a";
+ }
+
+ const char *includeOption(IncludeSearchPathType type)
+ {
+ switch (type) {
+ case IncludeSearchPathType::User:
+ case IncludeSearchPathType::System:
+ case IncludeSearchPathType::BuiltIn:
+ return "-isystem";
+ case IncludeSearchPathType::Framework:
+ return "-F";
+ case IncludeSearchPathType::Invalid:
+ return "";
+ }
+
+ return "-I";
+ }
+
+ void addLanguageVersion(const ProjectInfo &projectInfo)
+ {
+ if (projectInfo.languageExtension && Utils::LanguageExtension::Gnu)
+ commandLine.emplace_back(gnuLanguageVersion(projectInfo.languageVersion));
+ else
+ commandLine.emplace_back(standardLanguageVersion(projectInfo.languageVersion));
+ }
+
+ IncludeSearchPaths sortedIncludeSearchPaths(const IncludeSearchPaths &unsortedPaths)
+ {
+ IncludeSearchPaths paths = unsortedPaths;
+ std::sort(paths.begin(), paths.end(), [](const auto &first, const auto &second) {
+ return first.index < second.index;
+ });
+
+ return paths;
+ }
+
+ void addProjectIncludeSearchPaths(const IncludeSearchPaths &projectIncludeSearchPaths)
+ {
+ for (const IncludeSearchPath &path : projectIncludeSearchPaths) {
+ commandLine.emplace_back("-I");
+ commandLine.emplace_back(path.path);
+ }
+ }
+
+ void addSystemAndBuiltInIncludeSearchPaths(const IncludeSearchPaths &systemIncludeSearchPaths)
+ {
+ addSystemIncludeSearchPaths(systemIncludeSearchPaths);
+ addBuiltInSystemSearchPaths(systemIncludeSearchPaths);
+ }
+
+ void addSystemIncludeSearchPaths(const IncludeSearchPaths &systemIncludeSearchPaths)
+ {
+ for (const IncludeSearchPath &path : systemIncludeSearchPaths) {
+ if (path.type != IncludeSearchPathType::BuiltIn) {
+ commandLine.emplace_back(includeOption(path.type));
+ commandLine.emplace_back(path.path);
+ }
+ }
+ }
+
+ void addBuiltInSystemSearchPaths(const IncludeSearchPaths &systemIncludeSearchPaths)
+ {
+ for (const IncludeSearchPath &path : systemIncludeSearchPaths) {
+ if (path.type == IncludeSearchPathType::BuiltIn) {
+ commandLine.emplace_back(includeOption(path.type));
+ commandLine.emplace_back(path.path);
+ }
+ }
+ }
+
+ void addOutputPath(FilePathView outputPath)
+ {
+ if (!outputPath.isEmpty()) {
+ commandLine.emplace_back("-o");
+ commandLine.emplace_back(outputPath);
+ }
+ }
+
+ void addSourcePath(FilePathView sourcePath)
+ {
+ if (!sourcePath.isEmpty())
+ commandLine.emplace_back(sourcePath);
+ }
+
+ void addIncludePchPath(FilePathView includePchPath)
+ {
+ if (!includePchPath.isEmpty()) {
+ commandLine.emplace_back("-Xclang");
+ commandLine.emplace_back("-include-pch");
+ commandLine.emplace_back("-Xclang");
+ commandLine.emplace_back(includePchPath);
+ }
+ }
+
+ void addNoStdIncAndNoStdLibInc()
+ {
+ commandLine.emplace_back("-nostdinc");
+ commandLine.emplace_back("-nostdlibinc");
+ }
+
+public:
+ OutputContainer commandLine;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/filepath.h b/src/libs/clangsupport/filepath.h
index 9ff019de76..e08f3f4996 100644
--- a/src/libs/clangsupport/filepath.h
+++ b/src/libs/clangsupport/filepath.h
@@ -51,6 +51,14 @@ public:
m_slashIndex = view.slashIndex();
}
+ explicit FilePath(Utils::SmallStringView &&filePath)
+ : Utils::PathString(filePath)
+ {
+ FilePathView view{*this};
+
+ m_slashIndex = view.slashIndex();
+ }
+
FilePath(FilePathView filePathView)
: Utils::PathString(filePathView.toStringView()),
m_slashIndex(filePathView.slashIndex())
diff --git a/src/libs/clangsupport/filepathview.h b/src/libs/clangsupport/filepathview.h
index 27dac8377f..09b940fa61 100644
--- a/src/libs/clangsupport/filepathview.h
+++ b/src/libs/clangsupport/filepathview.h
@@ -37,6 +37,7 @@ template <char WindowsSlash>
class AbstractFilePathView : public Utils::SmallStringView
{
public:
+ constexpr AbstractFilePathView() = default;
explicit AbstractFilePathView(const char *const string, const size_type size) noexcept
: Utils::SmallStringView(string, size),
m_slashIndex(lastSlashIndex(*this))
diff --git a/src/libs/clangsupport/includesearchpath.h b/src/libs/clangsupport/includesearchpath.h
new file mode 100644
index 0000000000..239af9c1a4
--- /dev/null
+++ b/src/libs/clangsupport/includesearchpath.h
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <utils/smallstringio.h>
+
+#include <QDataStream>
+
+#include <vector>
+
+namespace ClangBackEnd {
+
+enum class IncludeSearchPathType : unsigned char {
+ Invalid,
+ User,
+ BuiltIn,
+ System,
+ Framework,
+};
+
+class IncludeSearchPath
+{
+public:
+ IncludeSearchPath() = default;
+ IncludeSearchPath(Utils::PathString &&path, int index, IncludeSearchPathType type)
+ : path(std::move(path))
+ , index(index)
+ , type(type)
+ {}
+
+ IncludeSearchPath(Utils::PathString &&path, int index, int type)
+ : path(std::move(path))
+ , index(index)
+ , type(static_cast<IncludeSearchPathType>(type))
+ {}
+
+ friend QDataStream &operator<<(QDataStream &out, const IncludeSearchPath &includeSearchPath)
+ {
+ out << includeSearchPath.path;
+ out << includeSearchPath.index;
+ out << static_cast<unsigned char>(includeSearchPath.type);
+
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, IncludeSearchPath &includeSearchPath)
+ {
+ unsigned char type;
+
+ in >> includeSearchPath.path;
+ in >> includeSearchPath.index;
+ in >> type;
+
+ includeSearchPath.type = static_cast<IncludeSearchPathType>(type);
+
+ return in;
+ }
+
+ friend bool operator==(const IncludeSearchPath &first, const IncludeSearchPath &second)
+ {
+ return std::tie(first.type, first.index, first.path)
+ == std::tie(second.type, second.index, second.path);
+ }
+
+ friend bool operator<(const IncludeSearchPath &first, const IncludeSearchPath &second)
+ {
+ return std::tie(first.path, first.index, first.type)
+ < std::tie(second.path, second.index, second.type);
+ }
+
+public:
+ Utils::PathString path;
+ int index = -1;
+ IncludeSearchPathType type = IncludeSearchPathType::Invalid;
+};
+
+using IncludeSearchPaths = std::vector<IncludeSearchPath>;
+
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/progresscounter.h b/src/libs/clangsupport/progresscounter.h
index 1958f6ef8c..fbdc9dda45 100644
--- a/src/libs/clangsupport/progresscounter.h
+++ b/src/libs/clangsupport/progresscounter.h
@@ -40,23 +40,29 @@ public:
void addTotal(int total)
{
- m_total += total;
+ if (total) {
+ m_total += total;
- m_progressCallback(m_progress, m_total);
+ m_progressCallback(m_progress, m_total);
+ }
}
void removeTotal(int total)
{
- m_total -= total;
+ if (total) {
+ m_total -= total;
- sendProgress();
+ sendProgress();
+ }
}
void addProgress(int progress)
{
- m_progress += progress;
+ if (progress) {
+ m_progress += progress;
- sendProgress();
+ sendProgress();
+ }
}
void sendProgress()
diff --git a/src/libs/clangsupport/projectpartcontainerv2.cpp b/src/libs/clangsupport/projectpartcontainer.cpp
index 7d03f9486d..a51e927db5 100644
--- a/src/libs/clangsupport/projectpartcontainerv2.cpp
+++ b/src/libs/clangsupport/projectpartcontainer.cpp
@@ -23,22 +23,19 @@
**
****************************************************************************/
-#include "projectpartcontainerv2.h"
+#include "projectpartcontainer.h"
namespace ClangBackEnd {
-namespace V2 {
QDebug operator<<(QDebug debug, const ProjectPartContainer &container)
{
debug.nospace() << "ProjectPartContainer("
<< container.projectPartId << ","
- << container.arguments << ", "
+ << container.toolChainArguments << ", "
<< container.headerPathIds << ", "
<< container.sourcePathIds
<< ")";
return debug;
}
-
-} // namespace V2
} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/projectpartcontainer.h b/src/libs/clangsupport/projectpartcontainer.h
new file mode 100644
index 0000000000..d805ef5aad
--- /dev/null
+++ b/src/libs/clangsupport/projectpartcontainer.h
@@ -0,0 +1,164 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "clangsupport_global.h"
+
+#include "compilermacro.h"
+#include "filepathid.h"
+#include "includesearchpath.h"
+
+#include <utils/cpplanguage_details.h>
+#include <utils/smallstringio.h>
+
+namespace ClangBackEnd {
+
+class ProjectPartContainer
+{
+ using uchar = unsigned char;
+public:
+ ProjectPartContainer() = default;
+ ProjectPartContainer(Utils::SmallString &&projectPartId,
+ Utils::SmallStringVector &&arguments,
+ CompilerMacros &&compilerMacros,
+ IncludeSearchPaths &&systemIncludeSearchPaths,
+ IncludeSearchPaths &&projectIncludeSearchPaths,
+ FilePathIds &&headerPathIds,
+ FilePathIds &&sourcePathIds,
+ Utils::Language language,
+ Utils::LanguageVersion languageVersion,
+ Utils::LanguageExtension languageExtension)
+ : projectPartId(std::move(projectPartId))
+ , toolChainArguments(std::move(arguments))
+ , compilerMacros(std::move(compilerMacros))
+ , systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
+ , projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
+ , headerPathIds(std::move(headerPathIds))
+ , sourcePathIds(std::move(sourcePathIds))
+ , language(language)
+ , languageVersion(languageVersion)
+ , languageExtension(languageExtension)
+ {
+ }
+
+ friend QDataStream &operator<<(QDataStream &out, const ProjectPartContainer &container)
+ {
+ out << container.projectPartId;
+ out << container.toolChainArguments;
+ out << container.compilerMacros;
+ out << container.systemIncludeSearchPaths;
+ out << container.projectIncludeSearchPaths;
+ out << container.headerPathIds;
+ out << container.sourcePathIds;
+ out << uchar(container.language);
+ out << uchar(container.languageVersion);
+ out << uchar(container.languageExtension);
+ return out;
+ }
+
+ friend QDataStream &operator>>(QDataStream &in, ProjectPartContainer &container)
+ {
+ uchar language;
+ uchar languageVersion;
+ uchar languageExtension;
+
+ in >> container.projectPartId;
+ in >> container.toolChainArguments;
+ in >> container.compilerMacros;
+ in >> container.systemIncludeSearchPaths;
+ in >> container.projectIncludeSearchPaths;
+ in >> container.headerPathIds;
+ in >> container.sourcePathIds;
+ in >> language;
+ in >> languageVersion;
+ in >> languageExtension;
+
+ container.language = static_cast<Utils::Language>(language);
+ container.languageVersion = static_cast<Utils::LanguageVersion>(languageVersion);
+ container.languageExtension = static_cast<Utils::LanguageExtension>(languageExtension);
+
+ return in;
+ }
+
+ friend bool operator==(const ProjectPartContainer &first, const ProjectPartContainer &second)
+ {
+ return first.projectPartId == second.projectPartId
+ && first.toolChainArguments == second.toolChainArguments
+ && first.compilerMacros == second.compilerMacros
+ && first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
+ && first.projectIncludeSearchPaths == second.projectIncludeSearchPaths
+ && first.headerPathIds == second.headerPathIds
+ && first.sourcePathIds == second.sourcePathIds&& first.language == second.language
+ && first.languageVersion == second.languageVersion
+ && first.languageExtension == second.languageExtension;
+ }
+
+ friend bool operator<(const ProjectPartContainer &first, const ProjectPartContainer &second)
+ {
+ return std::tie(first.projectPartId,
+ first.toolChainArguments,
+ first.compilerMacros,
+ first.systemIncludeSearchPaths,
+ first.projectIncludeSearchPaths,
+ first.headerPathIds,
+ first.sourcePathIds,
+ first.language,
+ first.languageVersion,
+ first.languageExtension)
+ < std::tie(second.projectPartId,
+ second.toolChainArguments,
+ second.compilerMacros,
+ second.systemIncludeSearchPaths,
+ second.projectIncludeSearchPaths,
+ second.headerPathIds,
+ second.sourcePathIds,
+ second.language,
+ second.languageVersion,
+ second.languageExtension);
+ }
+
+ ProjectPartContainer clone() const
+ {
+ return *this;
+ }
+
+public:
+ Utils::SmallString projectPartId;
+ Utils::SmallStringVector toolChainArguments;
+ CompilerMacros compilerMacros;
+ IncludeSearchPaths systemIncludeSearchPaths;
+ IncludeSearchPaths projectIncludeSearchPaths;
+ FilePathIds headerPathIds;
+ FilePathIds sourcePathIds;
+ Utils::Language language = Utils::Language::Cxx;
+ Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX98;
+ Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None;
+};
+
+using ProjectPartContainers = std::vector<ProjectPartContainer>;
+
+QDebug operator<<(QDebug debug, const ProjectPartContainer &container);
+} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/projectpartcontainerv2.h b/src/libs/clangsupport/projectpartcontainerv2.h
deleted file mode 100644
index be21ad874f..0000000000
--- a/src/libs/clangsupport/projectpartcontainerv2.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "clangsupport_global.h"
-
-#include "compilermacro.h"
-#include "filepathid.h"
-
-#include <utils/smallstringio.h>
-
-namespace ClangBackEnd {
-namespace V2 {
-
-class ProjectPartContainer
-{
-public:
- ProjectPartContainer() = default;
- ProjectPartContainer(Utils::SmallString &&projectPartId,
- Utils::SmallStringVector &&arguments,
- CompilerMacros &&compilerMacros,
- Utils::SmallStringVector &&includeSearchPaths,
- FilePathIds &&headerPathIds,
- FilePathIds &&sourcePathIds)
- : projectPartId(std::move(projectPartId)),
- arguments(std::move(arguments)),
- compilerMacros(std::move(compilerMacros)),
- includeSearchPaths(std::move(includeSearchPaths)),
- headerPathIds(std::move(headerPathIds)),
- sourcePathIds(std::move(sourcePathIds))
- {
- }
-
- friend QDataStream &operator<<(QDataStream &out, const ProjectPartContainer &container)
- {
- out << container.projectPartId;
- out << container.arguments;
- out << container.compilerMacros;
- out << container.includeSearchPaths;
- out << container.headerPathIds;
- out << container.sourcePathIds;
-
- return out;
- }
-
- friend QDataStream &operator>>(QDataStream &in, ProjectPartContainer &container)
- {
- in >> container.projectPartId;
- in >> container.arguments;
- in >> container.compilerMacros;
- in >> container.includeSearchPaths;
- in >> container.headerPathIds;
- in >> container.sourcePathIds;
-
- return in;
- }
-
- friend bool operator==(const ProjectPartContainer &first, const ProjectPartContainer &second)
- {
- return first.projectPartId == second.projectPartId
- && first.arguments == second.arguments
- && first.compilerMacros == second.compilerMacros
- && first.includeSearchPaths == second.includeSearchPaths
- && first.headerPathIds == second.headerPathIds
- && first.sourcePathIds == second.sourcePathIds;
- }
-
- friend bool operator<(const ProjectPartContainer &first, const ProjectPartContainer &second)
- {
- return std::tie(first.projectPartId,
- first.arguments,
- first.compilerMacros,
- first.includeSearchPaths,
- first.headerPathIds,
- first.sourcePathIds)
- < std::tie(second.projectPartId,
- second.arguments,
- second.compilerMacros,
- first.includeSearchPaths,
- second.headerPathIds,
- second.sourcePathIds);
- }
-
- ProjectPartContainer clone() const
- {
- return *this;
- }
-
-public:
- Utils::SmallString projectPartId;
- Utils::SmallStringVector arguments;
- CompilerMacros compilerMacros;
- Utils::SmallStringVector includeSearchPaths;
- FilePathIds headerPathIds;
- FilePathIds sourcePathIds;
-};
-
-using ProjectPartContainers = std::vector<ProjectPartContainer>;
-
-QDebug operator<<(QDebug debug, const ProjectPartContainer &container);
-} // namespace V2
-} // namespace ClangBackEnd
diff --git a/src/libs/clangsupport/projectpartpch.h b/src/libs/clangsupport/projectpartpch.h
index 6048a0b2f0..a413915b76 100644
--- a/src/libs/clangsupport/projectpartpch.h
+++ b/src/libs/clangsupport/projectpartpch.h
@@ -28,6 +28,7 @@
#include "clangsupport_global.h"
#include <utils/smallstringio.h>
+#include <filepath.h>
namespace ClangBackEnd {
@@ -36,15 +37,16 @@ class ProjectPartPch
public:
ProjectPartPch() = default;
ProjectPartPch(Utils::SmallString &&projectPartId,
- Utils::SmallString &&pchPath,
+ FilePath &&pchPath,
long long lastModified)
: projectPartId(std::move(projectPartId)),
pchPath(std::move(pchPath)),
lastModified(lastModified)
{}
+
ProjectPartPch(Utils::SmallStringView pchPath,
long long lastModified)
- : pchPath(pchPath),
+ : pchPath(FilePathView(pchPath)),
lastModified(lastModified)
{}
@@ -78,7 +80,7 @@ public:
public:
Utils::SmallString projectPartId;
- Utils::SmallString pchPath;
+ FilePath pchPath;
long long lastModified = -1;
};
diff --git a/src/libs/clangsupport/refactoringdatabaseinitializer.h b/src/libs/clangsupport/refactoringdatabaseinitializer.h
index 94665409fe..44c23e18a0 100644
--- a/src/libs/clangsupport/refactoringdatabaseinitializer.h
+++ b/src/libs/clangsupport/refactoringdatabaseinitializer.h
@@ -125,7 +125,8 @@ public:
const Sqlite::Column &projectPartNameColumn = table.addColumn("projectPartName", Sqlite::ColumnType::Text);
table.addColumn("compilerArguments", Sqlite::ColumnType::Text);
table.addColumn("compilerMacros", Sqlite::ColumnType::Text);
- table.addColumn("includeSearchPaths", Sqlite::ColumnType::Text);
+ table.addColumn("systemIncludeSearchPaths", Sqlite::ColumnType::Text);
+ table.addColumn("projectIncludeSearchPaths", Sqlite::ColumnType::Text);
table.addUniqueIndex({projectPartNameColumn});
table.initialize(database);
diff --git a/src/libs/clangsupport/removeprojectpartsmessage.h b/src/libs/clangsupport/removeprojectpartsmessage.h
index 1f45cc5f52..0aea092fea 100644
--- a/src/libs/clangsupport/removeprojectpartsmessage.h
+++ b/src/libs/clangsupport/removeprojectpartsmessage.h
@@ -25,7 +25,7 @@
#pragma once
-#include "projectpartcontainerv2.h"
+#include "projectpartcontainer.h"
namespace ClangBackEnd {
diff --git a/src/libs/clangsupport/updateprojectpartsmessage.h b/src/libs/clangsupport/updateprojectpartsmessage.h
index e923d7ba03..b1c6ca1f61 100644
--- a/src/libs/clangsupport/updateprojectpartsmessage.h
+++ b/src/libs/clangsupport/updateprojectpartsmessage.h
@@ -26,7 +26,7 @@
#pragma once
#include "filecontainerv2.h"
-#include "projectpartcontainerv2.h"
+#include "projectpartcontainer.h"
namespace ClangBackEnd {
@@ -34,11 +34,13 @@ class UpdateProjectPartsMessage
{
public:
UpdateProjectPartsMessage() = default;
- UpdateProjectPartsMessage(V2::ProjectPartContainers &&projectsParts)
+ UpdateProjectPartsMessage(ProjectPartContainers &&projectsParts,
+ Utils::SmallStringVector &&toolChainArguments)
: projectsParts(std::move(projectsParts))
+ , toolChainArguments(toolChainArguments)
{}
- V2::ProjectPartContainers takeProjectsParts()
+ ProjectPartContainers takeProjectsParts()
{
return std::move(projectsParts);
}
@@ -46,6 +48,7 @@ public:
friend QDataStream &operator<<(QDataStream &out, const UpdateProjectPartsMessage &message)
{
out << message.projectsParts;
+ out << message.toolChainArguments;
return out;
}
@@ -53,6 +56,7 @@ public:
friend QDataStream &operator>>(QDataStream &in, UpdateProjectPartsMessage &message)
{
in >> message.projectsParts;
+ in >> message.toolChainArguments;
return in;
}
@@ -60,7 +64,8 @@ public:
friend bool operator==(const UpdateProjectPartsMessage &first,
const UpdateProjectPartsMessage &second)
{
- return first.projectsParts == second.projectsParts;
+ return first.projectsParts == second.projectsParts
+ && first.toolChainArguments == second.toolChainArguments;
}
UpdateProjectPartsMessage clone() const
@@ -69,7 +74,8 @@ public:
}
public:
- V2::ProjectPartContainers projectsParts;
+ ProjectPartContainers projectsParts;
+ Utils::SmallStringVector toolChainArguments;
};
CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const UpdateProjectPartsMessage &message);
diff --git a/src/libs/utils/cpplanguage_details.h b/src/libs/utils/cpplanguage_details.h
index 1853d8ed0a..a4defb3262 100644
--- a/src/libs/utils/cpplanguage_details.h
+++ b/src/libs/utils/cpplanguage_details.h
@@ -60,4 +60,16 @@ enum class LanguageExtension : unsigned char {
Q_DECLARE_FLAGS(LanguageExtensions, LanguageExtension)
+constexpr enum LanguageExtension operator|(const LanguageExtension first,
+ const LanguageExtension second)
+{
+ return static_cast<LanguageExtension>(
+ (static_cast<unsigned char>(first) | static_cast<unsigned char>(second)));
+}
+
+constexpr bool operator&&(const LanguageExtension first, const LanguageExtension second)
+{
+ return static_cast<unsigned char>(first) & static_cast<unsigned char>(second);
+}
+
} // namespace Utils
diff --git a/src/plugins/clangpchmanager/projectupdater.cpp b/src/plugins/clangpchmanager/projectupdater.cpp
index a2c97c9d14..74b63a8f1a 100644
--- a/src/plugins/clangpchmanager/projectupdater.cpp
+++ b/src/plugins/clangpchmanager/projectupdater.cpp
@@ -36,6 +36,7 @@
#include <cpptools/compileroptionsbuilder.h>
#include <cpptools/projectpart.h>
+#include <cpptools/headerpathfilter.h>
#include <utils/algorithm.h>
@@ -64,10 +65,11 @@ ProjectUpdater::ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &s
{
}
-void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts)
+void ProjectUpdater::updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
+ Utils::SmallStringVector &&toolChainArguments)
{
- m_server.updateProjectParts(
- ClangBackEnd::UpdateProjectPartsMessage{toProjectPartContainers(projectParts)});
+ m_server.updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage{
+ toProjectPartContainers(projectParts), std::move(toolChainArguments)});
}
void ProjectUpdater::removeProjectParts(const QStringList &projectPartIds)
@@ -147,11 +149,21 @@ HeaderAndSources ProjectUpdater::headerAndSourcesFromProjectPart(
return headerAndSources;
}
-QStringList ProjectUpdater::compilerArguments(CppTools::ProjectPart *projectPart)
+QStringList ProjectUpdater::toolChainArguments(CppTools::ProjectPart *projectPart)
{
using CppTools::CompilerOptionsBuilder;
CompilerOptionsBuilder builder(*projectPart, CppTools::UseSystemHeader::Yes);
- return builder.build(CppTools::ProjectFile::CXXHeader, CppTools::UsePrecompiledHeaders::No);
+
+ builder.addWordWidth();
+ builder.addPicIfCompilerFlagsContainsIt();
+ builder.addTargetTriple();
+ builder.addExtraCodeModelFlags();
+ builder.undefineClangVersionMacrosForMsvc();
+ builder.undefineCppLanguageFeatureMacrosForMsvc2015();
+ builder.addProjectConfigFileInclude();
+ builder.addMsvcCompatibilityVersion();
+
+ return builder.options();
}
ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(const ProjectExplorer::Macros &projectMacros)
@@ -167,43 +179,102 @@ ClangBackEnd::CompilerMacros ProjectUpdater::createCompilerMacros(const ProjectE
return macros;
}
-Utils::SmallStringVector ProjectUpdater::createIncludeSearchPaths(
- const ProjectExplorer::HeaderPaths &projectPartHeaderPaths)
+namespace {
+ClangBackEnd::IncludeSearchPathType convertType(ProjectExplorer::HeaderPathType sourceType)
{
- Utils::SmallStringVector includePaths;
-
- for (const ProjectExplorer::HeaderPath &projectPartHeaderPath : projectPartHeaderPaths) {
- if (!projectPartHeaderPath.path.isEmpty())
- includePaths.emplace_back(projectPartHeaderPath.path);
+ using ProjectExplorer::HeaderPathType;
+ using ClangBackEnd::IncludeSearchPathType;
+
+ switch (sourceType) {
+ case HeaderPathType::User:
+ return IncludeSearchPathType::User;
+ case HeaderPathType::System:
+ return IncludeSearchPathType::System;
+ case HeaderPathType::BuiltIn:
+ return IncludeSearchPathType::BuiltIn;
+ case HeaderPathType::Framework:
+ return IncludeSearchPathType::Framework;
}
- std::sort(includePaths.begin(), includePaths.end());
+ return IncludeSearchPathType::Invalid;
+}
+
+ClangBackEnd::IncludeSearchPaths convertToIncludeSearchPaths(ProjectExplorer::HeaderPaths headerPaths)
+{
+ ClangBackEnd::IncludeSearchPaths paths;
+ paths.reserve(Utils::usize(headerPaths));
+
+ int index = 0;
+ for (const ProjectExplorer::HeaderPath &headerPath : headerPaths)
+ paths.emplace_back(headerPath.path, ++index, convertType(headerPath.type));
+
+ std::sort(paths.begin(), paths.end());
+
+ return paths;
+}
- return includePaths;
+ClangBackEnd::IncludeSearchPaths convertToIncludeSearchPaths(
+ ProjectExplorer::HeaderPaths headerPaths, ProjectExplorer::HeaderPaths headerPaths2)
+{
+ ClangBackEnd::IncludeSearchPaths paths;
+ paths.reserve(Utils::usize(headerPaths) + Utils::usize(headerPaths2));
+
+ int index = 0;
+ for (const ProjectExplorer::HeaderPath &headerPath : headerPaths)
+ paths.emplace_back(headerPath.path, ++index, convertType(headerPath.type));
+
+ for (const ProjectExplorer::HeaderPath &headerPath : headerPaths2)
+ paths.emplace_back(headerPath.path, ++index, convertType(headerPath.type));
+
+ std::sort(paths.begin(), paths.end());
+
+ return paths;
+}
+
+} // namespace
+
+ProjectUpdater::SystemAndProjectIncludeSearchPaths ProjectUpdater::createIncludeSearchPaths(
+ const CppTools::ProjectPart &projectPart)
+{
+ CppTools::HeaderPathFilter filter(projectPart,
+ CppTools::UseTweakedHeaderPaths::Yes,
+ CLANG_VERSION,
+ CLANG_RESOURCE_DIR);
+ filter.process();
+
+ return {convertToIncludeSearchPaths(filter.systemHeaderPaths, filter.builtInHeaderPaths),
+ convertToIncludeSearchPaths(filter.userHeaderPaths)};
}
-ClangBackEnd::V2::ProjectPartContainer ProjectUpdater::toProjectPartContainer(
+ClangBackEnd::ProjectPartContainer ProjectUpdater::toProjectPartContainer(
CppTools::ProjectPart *projectPart) const
{
- QStringList arguments = compilerArguments(projectPart);
+ QStringList arguments = toolChainArguments(projectPart);
HeaderAndSources headerAndSources = headerAndSourcesFromProjectPart(projectPart);
- return ClangBackEnd::V2::ProjectPartContainer(projectPart->id(),
- Utils::SmallStringVector(arguments),
- createCompilerMacros(projectPart->projectMacros),
- createIncludeSearchPaths(projectPart->headerPaths),
- std::move(headerAndSources.headers),
- std::move(headerAndSources.sources));
+ auto includeSearchPaths = createIncludeSearchPaths(*projectPart);
+
+ return ClangBackEnd::ProjectPartContainer(projectPart->id(),
+ Utils::SmallStringVector(arguments),
+ createCompilerMacros(projectPart->projectMacros),
+ std::move(includeSearchPaths.system),
+ std::move(includeSearchPaths.project),
+ std::move(headerAndSources.headers),
+ std::move(headerAndSources.sources),
+ projectPart->language,
+ projectPart->languageVersion,
+ static_cast<Utils::LanguageExtension>(
+ int(projectPart->languageExtensions)));
}
-std::vector<ClangBackEnd::V2::ProjectPartContainer> ProjectUpdater::toProjectPartContainers(
+ClangBackEnd::ProjectPartContainers ProjectUpdater::toProjectPartContainers(
std::vector<CppTools::ProjectPart *> projectParts) const
{
using namespace std::placeholders;
- std::vector<ClangBackEnd::V2::ProjectPartContainer> projectPartContainers;
+ std::vector<ClangBackEnd::ProjectPartContainer> projectPartContainers;
projectPartContainers.reserve(projectParts.size());
std::transform(projectParts.begin(),
diff --git a/src/plugins/clangpchmanager/projectupdater.h b/src/plugins/clangpchmanager/projectupdater.h
index fd4ff95538..896a02def0 100644
--- a/src/plugins/clangpchmanager/projectupdater.h
+++ b/src/plugins/clangpchmanager/projectupdater.h
@@ -31,6 +31,8 @@
#include <filecontainerv2.h>
#include <filepathcachinginterface.h>
#include <generatedfiles.h>
+#include <includesearchpath.h>
+#include <projectpartcontainer.h>
#include <projectexplorer/headerpath.h>
@@ -46,10 +48,6 @@ class ProjectFile;
namespace ClangBackEnd {
class ProjectManagementServerInterface;
-
-namespace V2 {
-class ProjectPartContainer;
-}
}
QT_FORWARD_DECLARE_CLASS(QStringList)
@@ -64,33 +62,39 @@ class PchManagerClient;
class CLANGPCHMANAGER_EXPORT ProjectUpdater
{
public:
+ struct SystemAndProjectIncludeSearchPaths
+ {
+ ClangBackEnd::IncludeSearchPaths system;
+ ClangBackEnd::IncludeSearchPaths project;
+ };
+
ProjectUpdater(ClangBackEnd::ProjectManagementServerInterface &server,
ClangBackEnd::FilePathCachingInterface &filePathCache);
- void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts);
+ void updateProjectParts(const std::vector<CppTools::ProjectPart *> &projectParts,
+ Utils::SmallStringVector &&toolChainArguments);
void removeProjectParts(const QStringList &projectPartIds);
void updateGeneratedFiles(ClangBackEnd::V2::FileContainers &&generatedFiles);
void removeGeneratedFiles(ClangBackEnd::FilePaths &&filePaths);
-unittest_public:
void setExcludedPaths(ClangBackEnd::FilePaths &&excludedPaths);
const ClangBackEnd::FilePaths &excludedPaths() const;
const ClangBackEnd::GeneratedFiles &generatedFiles() const;
HeaderAndSources headerAndSourcesFromProjectPart(CppTools::ProjectPart *projectPart) const;
- ClangBackEnd::V2::ProjectPartContainer toProjectPartContainer(
+ ClangBackEnd::ProjectPartContainer toProjectPartContainer(
CppTools::ProjectPart *projectPart) const;
- std::vector<ClangBackEnd::V2::ProjectPartContainer> toProjectPartContainers(
+ ClangBackEnd::ProjectPartContainers toProjectPartContainers(
std::vector<CppTools::ProjectPart *> projectParts) const;
void addToHeaderAndSources(HeaderAndSources &headerAndSources,
const CppTools::ProjectFile &projectFile) const;
- static QStringList compilerArguments(CppTools::ProjectPart *projectPart);
+ static QStringList toolChainArguments(CppTools::ProjectPart *projectPart);
static ClangBackEnd::CompilerMacros createCompilerMacros(
const ProjectExplorer::Macros &projectMacros);
- static Utils::SmallStringVector createIncludeSearchPaths(
- const ProjectExplorer::HeaderPaths &projectPartHeaderPaths);
+ static SystemAndProjectIncludeSearchPaths createIncludeSearchPaths(
+ const CppTools::ProjectPart &projectPart);
static ClangBackEnd::FilePaths createExcludedPaths(
const ClangBackEnd::V2::FileContainers &generatedFiles);
diff --git a/src/plugins/clangpchmanager/qtcreatorprojectupdater.h b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
index 9be66f1444..9521475692 100644
--- a/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
+++ b/src/plugins/clangpchmanager/qtcreatorprojectupdater.h
@@ -71,7 +71,8 @@ public:
void projectPartsUpdated(ProjectExplorer::Project *project)
{
- ProjectUpdaterType::updateProjectParts(Internal::createProjectParts(project));
+
+ ProjectUpdaterType::updateProjectParts(Internal::createProjectParts(project), {}); // TODO add support for toolchainarguments
}
void projectPartsRemoved(const QStringList &projectPartIds)
diff --git a/src/plugins/clangrefactoring/refactoringprojectupdater.cpp b/src/plugins/clangrefactoring/refactoringprojectupdater.cpp
index 648e458fd5..99b028e522 100644
--- a/src/plugins/clangrefactoring/refactoringprojectupdater.cpp
+++ b/src/plugins/clangrefactoring/refactoringprojectupdater.cpp
@@ -35,7 +35,7 @@ void RefactoringProjectUpdater::precompiledHeaderUpdated(const QString &projectP
{
auto projectPart = m_cppModelManager.projectPartForId(projectPartId);
if (projectPart)
- updateProjectParts({projectPart.data()});
+ updateProjectParts({projectPart.data()}, {});
}
void RefactoringProjectUpdater::precompiledHeaderRemoved(const QString &projectPartId)
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp
index c721946593..c3b8f115f2 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.cpp
+++ b/src/plugins/cpptools/compileroptionsbuilder.cpp
@@ -249,6 +249,12 @@ void CompilerOptionsBuilder::addExtraCodeModelFlags()
add(m_projectPart.extraCodeModelFlags);
}
+void CompilerOptionsBuilder::addPicIfCompilerFlagsContainsIt()
+{
+ if (m_projectPart.compilerFlags.contains("-fPIC"))
+ add("-fPIC");
+}
+
void CompilerOptionsBuilder::addCompilerFlags()
{
add(m_compilerFlags.flags);
diff --git a/src/plugins/cpptools/compileroptionsbuilder.h b/src/plugins/cpptools/compileroptionsbuilder.h
index 64c07b5fa3..0d0ca84488 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.h
+++ b/src/plugins/cpptools/compileroptionsbuilder.h
@@ -63,6 +63,7 @@ public:
void addTargetTriple();
void addExtraCodeModelFlags();
+ void addPicIfCompilerFlagsContainsIt();
void addCompilerFlags();
void insertWrappedQtHeaders();
void addLanguageVersionAndExtensions();
diff --git a/src/plugins/cpptools/cppprojectinfogenerator.cpp b/src/plugins/cpptools/cppprojectinfogenerator.cpp
index 29c251bdd4..c177c7a7d9 100644
--- a/src/plugins/cpptools/cppprojectinfogenerator.cpp
+++ b/src/plugins/cpptools/cppprojectinfogenerator.cpp
@@ -164,6 +164,7 @@ ProjectPart::Ptr ProjectInfoGenerator::createProjectPart(
part->extraCodeModelFlags = tcInfo.extraCodeModelFlags;
part->compilerFlags = flags.commandLineFlags;
part->warningFlags = flags.warningFlags;
+ part->language = language;
part->languageExtensions = flags.languageExtensions;
// Toolchain macros and language version
diff --git a/src/plugins/cpptools/projectpart.h b/src/plugins/cpptools/projectpart.h
index bd5fbee764..e357db3a3d 100644
--- a/src/plugins/cpptools/projectpart.h
+++ b/src/plugins/cpptools/projectpart.h
@@ -39,6 +39,8 @@
#include <cplusplus/Token.h>
+#include <utils/cpplanguage_details.h>
+
#include <QString>
#include <QSharedPointer>
@@ -91,6 +93,7 @@ public:
QString callGroupId;
// Versions, features and extensions
+ ::Utils::Language language = Utils::Language::Cxx;
::Utils::LanguageVersion languageVersion = ::Utils::LanguageVersion::LatestCxx;
::Utils::LanguageExtensions languageExtensions = ::Utils::LanguageExtension::None;
CPlusPlus::LanguageFeatures languageFeatures;
diff --git a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
index db4dc76aaa..4e2b19db8b 100644
--- a/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
+++ b/src/tools/clangpchmanagerbackend/clangpchmanagerbackendmain.cpp
@@ -23,18 +23,24 @@
**
****************************************************************************/
+#include <builddependenciesprovider.h>
+#include <builddependenciesstorage.h>
+#include <builddependencycollector.h>
#include <clangpathwatcher.h>
#include <connectionserver.h>
#include <environment.h>
#include <generatedfiles.h>
+#include <modifiedtimechecker.h>
#include <pchcreator.h>
#include <pchmanagerserver.h>
#include <pchmanagerclientproxy.h>
+#include <pchtaskgenerator.h>
+#include <pchtaskqueue.h>
+#include <pchtasksmerger.h>
#include <precompiledheaderstorage.h>
#include <processormanager.h>
#include <progresscounter.h>
#include <projectparts.h>
-#include <projectpartqueue.h>
#include <filepathcaching.h>
#include <refactoringdatabaseinitializer.h>
#include <sqlitedatabase.h>
@@ -42,12 +48,12 @@
#include <QCommandLineParser>
#include <QCoreApplication>
+#include <QDateTime>
#include <QFileSystemWatcher>
#include <QLoggingCategory>
#include <QProcess>
#include <QTemporaryDir>
#include <QTimer>
-
#include <chrono>
#include <thread>
@@ -62,6 +68,8 @@ using ClangBackEnd::PchManagerServer;
using ClangBackEnd::PrecompiledHeaderStorage;
using ClangBackEnd::ProjectParts;
using ClangBackEnd::FilePathCache;
+using ClangBackEnd::FilePathView;
+using ClangBackEnd::TimeStamp;
class PchManagerApplication final : public QCoreApplication
{
@@ -93,11 +101,6 @@ public:
return m_pchBuildDirectoryPath;
}
- QString clangCompilerPath() const override
- {
- return QString(CLANG_COMPILER_PATH);
- }
-
uint hardwareConcurrency() const override
{
return std::thread::hardware_concurrency();
@@ -132,13 +135,11 @@ public:
PchCreatorManager(const ClangBackEnd::GeneratedFiles &generatedFiles,
ClangBackEnd::Environment &environment,
Sqlite::Database &database,
- PchManagerServer &pchManagerServer,
- ClangBackEnd::ClangPathWatcherInterface &fileSystemWatcher)
+ PchManagerServer &pchManagerServer)
: ProcessorManager(generatedFiles),
m_environment(environment),
m_database(database),
- m_pchManagerServer(pchManagerServer),
- m_fileSystemWatcher(fileSystemWatcher)
+ m_pchManagerServer(pchManagerServer)
{}
protected:
@@ -146,25 +147,22 @@ protected:
{
return std::make_unique<PchCreator>(m_environment,
m_database,
- *m_pchManagerServer.client(),
- m_fileSystemWatcher);
+ *m_pchManagerServer.client());
}
private:
ClangBackEnd::Environment &m_environment;
Sqlite::Database &m_database;
ClangBackEnd::PchManagerServer &m_pchManagerServer;
- ClangBackEnd::ClangPathWatcherInterface &m_fileSystemWatcher;
};
struct Data // because we have a cycle dependency
{
- using TaskScheduler = ClangBackEnd::TaskScheduler<PchCreatorManager, ClangBackEnd::ProjectPartQueue::Task>;
+ using TaskScheduler = ClangBackEnd::TaskScheduler<PchCreatorManager, ClangBackEnd::PchTaskQueue::Task>;
- Data(const QString &databasePath,
- const QString &pchsPath)
- : database{Utils::PathString{databasePath}, 100000ms},
- environment{pchsPath}
+ Data(const QString &databasePath, const QString &pchsPath)
+ : database{Utils::PathString{databasePath}, 100000ms}
+ , environment{pchsPath}
{}
Sqlite::Database database;
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
@@ -173,12 +171,39 @@ struct Data // because we have a cycle dependency
ApplicationEnvironment environment;
ProjectParts projectParts;
GeneratedFiles generatedFiles;
- PchCreatorManager pchCreatorManager{generatedFiles, environment, database, clangPchManagerServer, includeWatcher};
+ PchCreatorManager pchCreatorManager{generatedFiles, environment, database, clangPchManagerServer};
PrecompiledHeaderStorage<> preCompiledHeaderStorage{database};
- ClangBackEnd::ProgressCounter progressCounter{[&] (int progress, int total) { clangPchManagerServer.setProgress(progress, total); }};
- TaskScheduler taskScheduler{pchCreatorManager, projectPartQueue, progressCounter, std::thread::hardware_concurrency()};
- ClangBackEnd::ProjectPartQueue projectPartQueue{taskScheduler, preCompiledHeaderStorage, database, progressCounter};
- PchManagerServer clangPchManagerServer{includeWatcher, projectPartQueue, projectParts, generatedFiles};
+ ClangBackEnd::ProgressCounter progressCounter{
+ [&](int progress, int total) { clangPchManagerServer.setProgress(progress, total); }};
+ TaskScheduler systemTaskScheduler{pchCreatorManager,
+ pchTaskQueue,
+ progressCounter,
+ std::thread::hardware_concurrency(),
+ ClangBackEnd::CallDoInMainThreadAfterFinished::No};
+ TaskScheduler projectTaskScheduler{pchCreatorManager,
+ pchTaskQueue,
+ progressCounter,
+ std::thread::hardware_concurrency(),
+ ClangBackEnd::CallDoInMainThreadAfterFinished::Yes};
+ ClangBackEnd::PchTaskQueue pchTaskQueue{systemTaskScheduler,
+ projectTaskScheduler,
+ progressCounter,
+ preCompiledHeaderStorage,
+ database};
+ ClangBackEnd::PchTasksMerger pchTaskMerger{pchTaskQueue};
+ ClangBackEnd::BuildDependenciesStorage<> buildDependencyStorage{database};
+ ClangBackEnd::BuildDependencyCollector buildDependencyCollector{filePathCache};
+ std::function<TimeStamp(FilePathView filePath)> getModifiedTime{
+ [&](ClangBackEnd::FilePathView path) -> TimeStamp {
+ return QFileInfo(QString(path)).lastModified().toSecsSinceEpoch();
+ }};
+ ClangBackEnd::ModifiedTimeChecker modifiedTimeChecker{getModifiedTime, filePathCache};
+ ClangBackEnd::BuildDependenciesProvider buildDependencyProvider{buildDependencyStorage,
+ modifiedTimeChecker,
+ buildDependencyCollector,
+ database};
+ ClangBackEnd::PchTaskGenerator pchTaskGenerator{buildDependencyProvider, pchTaskMerger};
+ PchManagerServer clangPchManagerServer{includeWatcher, pchTaskGenerator, projectParts, generatedFiles};
};
int main(int argc, char *argv[])
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp
index 7f97599fac..d58da0f27c 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp
@@ -53,7 +53,7 @@ OutputContainer setUnion(InputContainer1 &&input1,
return results;
}
-BuildDependency BuildDependenciesProvider::create(const V2::ProjectPartContainer &projectPart)
+BuildDependency BuildDependenciesProvider::create(const ProjectPartContainer &projectPart)
{
SourceEntries includes = createSourceEntriesFromStorage(projectPart.sourcePathIds,
projectPart.projectPartId);
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h
index 386eca587e..4a89ace732 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h
@@ -50,7 +50,7 @@ public:
, m_transactionBackend(transactionBackend)
{}
- BuildDependency create(const V2::ProjectPartContainer &projectPart) override;
+ BuildDependency create(const ProjectPartContainer &projectPart) override;
private:
BuildDependency createBuildDependencyFromStorage(SourceEntries &&includes) const;
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h b/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h
index 0bfaeed06c..7af8c054cc 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependenciesproviderinterface.h
@@ -27,14 +27,14 @@
#include "builddependency.h"
-#include "projectpartcontainerv2.h"
+#include "projectpartcontainer.h"
namespace ClangBackEnd {
class BuildDependenciesProviderInterface
{
public:
- virtual BuildDependency create(const V2::ProjectPartContainer &projectPart) = 0;
+ virtual BuildDependency create(const ProjectPartContainer &projectPart) = 0;
protected:
~BuildDependenciesProviderInterface() = default;
diff --git a/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp b/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp
index 4ba3e8c0e6..bfbfbf20cd 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp
+++ b/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp
@@ -26,6 +26,7 @@
#include "builddependencycollector.h"
#include "collectbuilddependencytoolaction.h"
+#include "commandlinebuilder.h"
#include <utils/smallstring.h>
@@ -44,9 +45,12 @@ FilePathIds operator+(const FilePathIds &first, const FilePathIds &second)
}
}
-BuildDependency BuildDependencyCollector::create(const V2::ProjectPartContainer &projectPart)
+BuildDependency BuildDependencyCollector::create(const ProjectPartContainer &projectPart)
{
- addFiles(projectPart.sourcePathIds, projectPart.arguments);
+ CommandLineBuilder<ProjectPartContainer, Utils::SmallStringVector> builder{
+ projectPart, projectPart.toolChainArguments};
+
+ addFiles(projectPart.sourcePathIds, builder.commandLine);
setExcludedFilePaths(
m_filePathCache.filePaths(projectPart.headerPathIds + projectPart.sourcePathIds));
diff --git a/src/tools/clangpchmanagerbackend/source/builddependencycollector.h b/src/tools/clangpchmanagerbackend/source/builddependencycollector.h
index cab749c316..2ea7fb7c90 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependencycollector.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependencycollector.h
@@ -42,7 +42,7 @@ public:
{
}
- BuildDependency create(const V2::ProjectPartContainer &projectPart) override;
+ BuildDependency create(const ProjectPartContainer &projectPart) override;
void collect();
diff --git a/src/tools/clangpchmanagerbackend/source/builddependencygeneratorinterface.h b/src/tools/clangpchmanagerbackend/source/builddependencygeneratorinterface.h
index f6e13f3a1a..0c368e7e25 100644
--- a/src/tools/clangpchmanagerbackend/source/builddependencygeneratorinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/builddependencygeneratorinterface.h
@@ -27,14 +27,14 @@
#include "builddependency.h"
-#include "projectpartcontainerv2.h"
+#include "projectpartcontainer.h"
namespace ClangBackEnd {
class BuildDependencyGeneratorInterface
{
public:
- virtual BuildDependency create(const V2::ProjectPartContainer &projectPart) = 0;
+ virtual BuildDependency create(const ProjectPartContainer &projectPart) = 0;
protected:
~BuildDependencyGeneratorInterface() = default;
diff --git a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
index 693e110402..fa8d6e527a 100644
--- a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
+++ b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri
@@ -4,7 +4,6 @@ SOURCES += \
$$PWD/builddependenciesprovider.cpp \
$$PWD/pchmanagerserver.cpp \
$$PWD/projectparts.cpp \
- $$PWD/projectpartqueue.cpp \
$$PWD/pchtaskgenerator.cpp \
$$PWD/pchtasksmerger.cpp \
$$PWD/pchtaskqueue.cpp
@@ -17,9 +16,7 @@ HEADERS += \
$$PWD/projectparts.h \
$$PWD/pchcreatorinterface.h \
$$PWD/projectpartsinterface.h \
- $$PWD/projectpartqueue.h \
$$PWD/queueinterface.h \
- $$PWD/projectpartqueueinterface.h \
$$PWD/processormanagerinterface.h \
$$PWD/processorinterface.h \
$$PWD/taskscheduler.h \
@@ -40,7 +37,11 @@ HEADERS += \
$$PWD/pchtasksmergerinterface.h \
$$PWD/pchtasksmerger.h \
$$PWD/pchtaskqueueinterface.h \
- $$PWD/pchtaskqueue.h
+ $$PWD/pchtaskqueue.h \
+ $$PWD/generatepchactionfactory.h \
+ $$PWD/pchtaskgeneratorinterface.h \
+ $$PWD/toolchainargumentscache.h \
+ $$PWD/modifiedtimechecker.h
!isEmpty(LIBTOOLING_LIBS) {
SOURCES += \
diff --git a/src/tools/clangpchmanagerbackend/source/environment.h b/src/tools/clangpchmanagerbackend/source/environment.h
index a7deea2b80..7f575fe169 100644
--- a/src/tools/clangpchmanagerbackend/source/environment.h
+++ b/src/tools/clangpchmanagerbackend/source/environment.h
@@ -37,7 +37,6 @@ public:
Environment &operator=(const Environment &) = delete;
virtual QString pchBuildDirectory() const = 0;
- virtual QString clangCompilerPath() const = 0;
virtual uint hardwareConcurrency() const = 0;
protected:
diff --git a/src/tools/clangpchmanagerbackend/source/generatepchactionfactory.h b/src/tools/clangpchmanagerbackend/source/generatepchactionfactory.h
new file mode 100644
index 0000000000..47a64eda92
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/generatepchactionfactory.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <clang/Tooling/Tooling.h>
+
+#include "clang/Frontend/FrontendActions.h"
+
+namespace ClangBackEnd {
+class GeneratePCHActionFactory final : public clang::tooling::FrontendActionFactory
+{
+public:
+ clang::FrontendAction *create() override
+ {
+ return new clang::GeneratePCHAction;
+ }
+};
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/modifiedtimechecker.h b/src/tools/clangpchmanagerbackend/source/modifiedtimechecker.h
new file mode 100644
index 0000000000..9e67a27b14
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/modifiedtimechecker.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "modifiedtimecheckerinterface.h"
+
+#include <filepathcachinginterface.h>
+
+#include <algorithm>
+#include <iterator>
+
+namespace ClangBackEnd {
+
+class ModifiedTimeChecker final : public ModifiedTimeCheckerInterface
+{
+public:
+ using GetModifiedTime = std::function<ClangBackEnd::TimeStamp(ClangBackEnd::FilePathView filePath)>;
+ ModifiedTimeChecker(GetModifiedTime &getModifiedTime, FilePathCachingInterface &filePathCache)
+ : m_getModifiedTime(getModifiedTime)
+ , m_filePathCache(filePathCache)
+ {}
+
+ bool isUpToDate(const SourceEntries &sourceEntries) const
+ {
+ if (sourceEntries.empty())
+ return false;
+
+ updateCurrentSourceTimeStamps(sourceEntries);
+
+ return compareEntries(sourceEntries);
+ }
+
+ void pathsChanged(const FilePathIds &filePathIds)
+ {
+ using SourceTimeStampPointers = std::vector<SourceTimeStamp*>;
+
+ class BackInserterIterator : public std::back_insert_iterator<SourceTimeStampPointers>
+ {
+ public:
+ BackInserterIterator(SourceTimeStampPointers &container)
+ : std::back_insert_iterator<SourceTimeStampPointers>(container)
+ {}
+
+ BackInserterIterator &operator=(SourceTimeStamp &timeStamp)
+ {
+ container->push_back(&timeStamp);
+
+ return *this;
+ }
+
+ BackInserterIterator &operator*() { return *this; }
+ };
+
+ SourceTimeStampPointers timeStampsToUpdate;
+ timeStampsToUpdate.reserve(filePathIds.size());
+
+ std::set_intersection(m_currentSourceTimeStamps.begin(),
+ m_currentSourceTimeStamps.end(),
+ filePathIds.begin(),
+ filePathIds.end(),
+ BackInserterIterator(timeStampsToUpdate));
+
+ for (SourceTimeStamp *sourceTimeStamp : timeStampsToUpdate) {
+ sourceTimeStamp->lastModified = m_getModifiedTime(
+ m_filePathCache.filePath(sourceTimeStamp->sourceId));
+ }
+ }
+
+private:
+ bool compareEntries(const SourceEntries &sourceEntries) const
+ {
+ SourceTimeStamps currentSourceTimeStamp;
+ currentSourceTimeStamp.reserve(sourceEntries.size());
+ std::set_intersection(m_currentSourceTimeStamps.begin(),
+ m_currentSourceTimeStamps.end(),
+ sourceEntries.begin(),
+ sourceEntries.end(),
+ std::back_inserter(currentSourceTimeStamp));
+
+ return std::equal(currentSourceTimeStamp.begin(),
+ currentSourceTimeStamp.end(),
+ sourceEntries.begin(),
+ sourceEntries.end(),
+ [](SourceTimeStamp first, SourceTimeStamp second) {
+ return first.lastModified <= second.lastModified;
+ });
+ }
+
+ void updateCurrentSourceTimeStamps(const SourceEntries &sourceEntries) const
+ {
+ SourceTimeStamps sourceTimeStamps = newSourceTimeStamps(sourceEntries);
+
+ for (SourceTimeStamp &newSourceTimeStamp : sourceTimeStamps) {
+ newSourceTimeStamp.lastModified = m_getModifiedTime(
+ m_filePathCache.filePath(newSourceTimeStamp.sourceId));
+ }
+
+ auto split = sourceTimeStamps.insert(sourceTimeStamps.end(),
+ m_currentSourceTimeStamps.begin(),
+ m_currentSourceTimeStamps.end());
+ std::inplace_merge(sourceTimeStamps.begin(), split, sourceTimeStamps.end());
+
+ m_currentSourceTimeStamps = sourceTimeStamps;
+ }
+
+ SourceTimeStamps newSourceTimeStamps(const SourceEntries &sourceEntries) const
+ {
+ SourceTimeStamps newTimeStamps;
+ newTimeStamps.reserve(sourceEntries.size() + m_currentSourceTimeStamps.size());
+
+ std::set_difference(sourceEntries.begin(),
+ sourceEntries.end(),
+ m_currentSourceTimeStamps.begin(),
+ m_currentSourceTimeStamps.end(),
+ std::back_inserter(newTimeStamps));
+
+ return newTimeStamps;
+ }
+
+private:
+ mutable SourceTimeStamps m_currentSourceTimeStamps;
+ GetModifiedTime &m_getModifiedTime;
+ FilePathCachingInterface &m_filePathCache;
+};
+
+} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
index 79062b5e2d..ea9d7c3e37 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp
@@ -25,8 +25,10 @@
#include "pchcreator.h"
-#include "environment.h"
#include "builddependencycollector.h"
+#include "commandlinebuilder.h"
+#include "environment.h"
+#include "generatepchactionfactory.h"
#include "pchnotcreatederror.h"
#include <clangpathwatcherinterface.h>
@@ -45,41 +47,6 @@
namespace ClangBackEnd {
namespace {
-template <typename Source,
- typename Target>
-void append(Target &target, const Source &source)
-{
- using ValueType = typename Target::value_type;
- Source clonedSource = source.clone();
-
- target.reserve(target.size() + source.size());
-
- for (auto &&entry : clonedSource)
- target.push_back(ValueType(std::move(entry)));
-}
-
-void appendFilePathId(ClangBackEnd::FilePaths &target,
- const ClangBackEnd::FilePathIds &source,
- const ClangBackEnd::FilePathCachingInterface &filePathCache)
-{
- for (FilePathId id : source)
- target.emplace_back(filePathCache.filePath(id));
-}
-
-Utils::PathStringVector generatedFilePaths(const V2::FileContainers &generaredFiles)
-{
- Utils::PathStringVector generaredFilePaths;
- generaredFilePaths.reserve(generaredFiles.size());
-
- for (const V2::FileContainer &generatedFile : generaredFiles)
- generaredFilePaths.push_back(generatedFile.filePath.path());
-
- return generaredFilePaths;
-}
-
-}
-
-namespace {
std::size_t contentSize(const FilePaths &includes)
{
@@ -106,239 +73,72 @@ Utils::SmallString PchCreator::generatePchIncludeFileContent(const FilePathIds &
}
-bool PchCreator::generatePch(Utils::SmallStringVector &&compilerArguments)
-{
- QProcess process;
-
- process.setProcessChannelMode(QProcess::ForwardedChannels);
- process.setArguments(QStringList(compilerArguments));
- process.setProgram(QString(m_environment.clangCompilerPath()));
-
- process.start();
- process.waitForFinished(300000);
-
- return process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0;
-}
-
-QStringList PchCreator::convertToQStringList(const Utils::SmallStringVector &compilerArguments)
-{
- QStringList qStringList;
-
- append(qStringList, compilerArguments);
-
- return qStringList;
-}
-
-namespace {
-
-void hashProjectPart(QCryptographicHash &hash, const V2::ProjectPartContainer &projectPart)
-{
- const auto &projectPartId = projectPart.projectPartId;
- hash.addData(projectPartId.data(), int(projectPartId.size()));
-
- for (const auto &argument : projectPart.arguments)
- hash.addData(argument.data(), int(argument.size()));
-}
-}
-
-Utils::SmallStringVector PchCreator::generateProjectPartCommandLine(
- const V2::ProjectPartContainer &projectPart) const
-{
- const Utils::SmallStringVector &arguments = projectPart.arguments;
-
- Utils::SmallStringVector commandLine;
- commandLine.reserve(arguments.size() + 1);
-
- commandLine.emplace_back(m_environment.clangCompilerPath());
-
- append(commandLine , arguments);
-
- return commandLine;
-}
-
-Utils::SmallString PchCreator::generateProjectPartPchFilePathWithoutExtension(
- const V2::ProjectPartContainer &projectPart) const
-{
- QByteArray fileName = m_environment.pchBuildDirectory().toUtf8();
- fileName += '/';
- fileName += projectPartHash(projectPart);
-
- return Utils::SmallString::fromQByteArray(fileName);
-}
-
-Utils::PathStringVector PchCreator::generateProjectPartHeaders(
- const V2::ProjectPartContainer &projectPart) const
-{
- Utils::PathStringVector headerPaths;
- headerPaths.reserve(projectPart.headerPathIds.size() + m_unsavedFiles.size());
-
- std::transform(projectPart.headerPathIds.begin(),
- projectPart.headerPathIds.end(),
- std::back_inserter(headerPaths),
- [&] (FilePathId filePathId) {
- return m_filePathCache.filePath(filePathId);
- });
-
- Utils::PathStringVector generatedPath = generatedFilePaths(m_unsavedFiles);
-
- std::copy(std::make_move_iterator(generatedPath.begin()),
- std::make_move_iterator(generatedPath.end()),
- std::back_inserter(headerPaths));
-
- return headerPaths;
-}
-
-namespace {
-
-std::size_t sizeOfContent(const ClangBackEnd::FilePaths &paths)
-{
- return std::accumulate(paths.begin(),
- paths.end(),
- std::size_t(0),
- [] (std::size_t size, const auto &path) {
- const char includeTemplate[] = "#include \"\"\n";
- return size + path.size() + sizeof(includeTemplate);
- });
-}
-
-Utils::SmallString concatContent(const ClangBackEnd::FilePaths &paths, std::size_t size)
-{
- Utils::SmallString content;
- content.reserve(size);
-
- for (const ClangBackEnd::FilePath &path : paths) {
- content += "#include \"";
- content += path;
- content += "\"\n";
- };
-
- return content;
-}
-
-}
-
-Utils::SmallString PchCreator::generateProjectPartSourcesContent(
- const V2::ProjectPartContainer &projectPart) const
-{
- ClangBackEnd::FilePaths paths = generateProjectPartSourcePaths(projectPart);
-
- return concatContent(paths, sizeOfContent(paths));
-}
-
-ClangBackEnd::FilePaths PchCreator::generateProjectPartSourcePaths(
- const V2::ProjectPartContainer &projectPart) const
-{
- ClangBackEnd::FilePaths includeAndSources;
- includeAndSources.reserve(projectPart.sourcePathIds.size());
-
- appendFilePathId(includeAndSources, projectPart.sourcePathIds, m_filePathCache);
-
- return includeAndSources;
-}
-
-SourceEntries PchCreator::generateProjectPartPchIncludes(
- const V2::ProjectPartContainer &projectPart) const
+bool PchCreator::generatePch()
{
- Utils::SmallString jointedFileContent = generateProjectPartSourcesContent(projectPart);
- Utils::SmallString jointedFilePath = generateProjectPartSourceFilePath(projectPart);
- auto jointFile = generateFileWithContent(jointedFilePath, jointedFileContent);
- Utils::SmallStringVector arguments = generateProjectPartCommandLine(projectPart);
- FilePath filePath{Utils::PathString(jointedFilePath)};
-
- BuildDependencyCollector collector(m_filePathCache);
-
- collector.setExcludedFilePaths(generateProjectPartSourcePaths(projectPart));
+ clang::tooling::ClangTool tool = m_clangTool.createOutputTool();
- collector.addFile(filePath, projectPart.sourcePathIds, arguments);
+ auto action = std::make_unique<GeneratePCHActionFactory>();
- collector.addUnsavedFiles(m_unsavedFiles);
-
- collector.collect();
-
- jointFile->remove();
-
- return collector.includeIds();
+ return tool.run(action.get()) != 1;
}
-Utils::SmallString PchCreator::generateProjectPathPchHeaderFilePath(
- const V2::ProjectPartContainer &projectPart) const
+FilePath PchCreator::generatePchHeaderFilePath() const
{
- return Utils::SmallString{generateProjectPartPchFilePathWithoutExtension(projectPart), ".h"};
-}
+ std::uniform_int_distribution<std::mt19937_64::result_type> distribution;
-Utils::SmallString PchCreator::generateProjectPartPchFilePath(
- const V2::ProjectPartContainer &projectPart) const
-{
- return Utils::SmallString{generateProjectPartPchFilePathWithoutExtension(projectPart), ".pch"};
+ return FilePathView{Utils::PathString{Utils::SmallString(m_environment.pchBuildDirectory()),
+ "/",
+ std::to_string(distribution(randomNumberGenator)),
+ ".h"}};
}
-Utils::SmallString PchCreator::generateProjectPartSourceFilePath(const V2::ProjectPartContainer &projectPart) const
+FilePath PchCreator::generatePchFilePath() const
{
- return Utils::SmallString{generateProjectPartPchFilePathWithoutExtension(projectPart), ".cpp"};
-}
+ std::uniform_int_distribution<std::uint_fast64_t> distribution(
+ 1, std::numeric_limits<std::uint_fast64_t>::max());
-Utils::SmallStringVector PchCreator::generateProjectPartPchCompilerArguments(
- const V2::ProjectPartContainer &projectPart) const
-{
- Utils::SmallStringVector arguments;
- arguments.reserve(5);
-
- arguments.emplace_back("-x");
- arguments.emplace_back("c++-header");
- arguments.emplace_back("-Xclang");
- arguments.emplace_back("-emit-pch");
- arguments.emplace_back("-o");
- arguments.emplace_back(generateProjectPartPchFilePath(projectPart));
- arguments.emplace_back(generateProjectPathPchHeaderFilePath(projectPart));
-
- return arguments;
+ return FilePathView{Utils::PathString{Utils::SmallString(m_environment.pchBuildDirectory()),
+ "/",
+ std::to_string(distribution(randomNumberGenator)),
+ ".pch"}};
}
-Utils::SmallStringVector PchCreator::generateProjectPartClangCompilerArguments(
- const V2::ProjectPartContainer &projectPart) const
+std::vector<std::string> PchCreator::generateClangCompilerArguments(
+ PchTask &&pchTask,
+ FilePathView sourceFilePath,
+ FilePathView pchOutputPath)
{
- Utils::SmallStringVector compilerArguments = projectPart.arguments.clone();
- const auto pchArguments = generateProjectPartPchCompilerArguments(projectPart);
-
- append(compilerArguments, pchArguments);
+ CommandLineBuilder<PchTask> builder{pchTask,
+ pchTask.toolChainArguments,
+ sourceFilePath,
+ pchOutputPath,
+ pchTask.systemPchPath};
- return compilerArguments;
+ return builder.commandLine;
}
-IdPaths PchCreator::generateProjectPartPch(const V2::ProjectPartContainer &projectPart)
+void PchCreator::generatePch(PchTask &&pchTask)
{
long long lastModified = QDateTime::currentSecsSinceEpoch();
- auto includes = generateProjectPartPchIncludes(projectPart);
- auto content = generatePchIncludeFileContent(topIncludeIds(includes));
- auto pchIncludeFilePath = generateProjectPathPchHeaderFilePath(projectPart);
- auto pchFilePath = generateProjectPartPchFilePath(projectPart);
- generateFileWithContent(pchIncludeFilePath, content);
+ auto content = generatePchIncludeFileContent(pchTask.includes);
+ auto pchSourceFilePath = generatePchHeaderFilePath();
+ auto pchOutputPath = generatePchFilePath();
+ generateFileWithContent(pchSourceFilePath, content);
- bool success = generatePch(generateProjectPartClangCompilerArguments(projectPart));
+ m_clangTool.addFile(
+ pchSourceFilePath.directory(),
+ pchSourceFilePath.name(),
+ "",
+ generateClangCompilerArguments(std::move(pchTask), pchSourceFilePath, pchOutputPath));
- m_projectPartPch.projectPartId = projectPart.projectPartId;
+ bool success = generatePch();
+
+ m_projectPartPch.projectPartId = pchTask.projectPartId();
if (success) {
- m_projectPartPch.pchPath = std::move(pchFilePath);
+ m_projectPartPch.pchPath = std::move(pchOutputPath);
m_projectPartPch.lastModified = lastModified;
}
-
- return {projectPart.projectPartId.clone(), allIncludeIds(includes)};
-}
-
-void PchCreator::generatePchDeprecated(const V2::ProjectPartContainer &projectPart)
-{
- m_projectIncludeIds = generateProjectPartPch(projectPart);
-}
-
-void PchCreator::generatePch(const PchTask &pchTask)
-{
-
-}
-
-IdPaths PchCreator::takeProjectIncludes()
-{
- return std::move(m_projectIncludeIds);
}
const ProjectPartPch &PchCreator::projectPartPch()
@@ -363,19 +163,12 @@ bool PchCreator::isUsed() const
void PchCreator::clear()
{
- m_projectPartPch = ProjectPartPch{};
- m_projectIncludeIds = IdPaths{};
+ m_projectPartPch = {};
}
void PchCreator::doInMainThreadAfterFinished()
{
m_pchManagerClient.precompiledHeadersUpdated(ProjectPartPchs{m_projectPartPch});
- m_fileSystemWatcher.updateIdPaths({takeProjectIncludes()});
-}
-
-const IdPaths &PchCreator::projectIncludes() const
-{
- return m_projectIncludeIds;
}
const FilePathCaching &PchCreator::filePathCache()
@@ -383,9 +176,8 @@ const FilePathCaching &PchCreator::filePathCache()
return m_filePathCache;
}
-std::unique_ptr<QFile> PchCreator::generateFileWithContent(
- const Utils::SmallString &filePath,
- const Utils::SmallString &content)
+std::unique_ptr<QFile> PchCreator::generateFileWithContent(const Utils::SmallString &filePath,
+ const Utils::SmallString &content)
{
std::unique_ptr<QFile> precompiledIncludeFile(new QFile(QString(filePath)));
@@ -397,41 +189,4 @@ std::unique_ptr<QFile> PchCreator::generateFileWithContent(
return precompiledIncludeFile;
}
-FilePathIds PchCreator::topIncludeIds(const SourceEntries &includes)
-{
- FilePathIds topIncludes;
- topIncludes.reserve(includes.size());
-
- for (SourceEntry include : includes) {
- if (include.sourceType == SourceType::TopProjectInclude)
- topIncludes.push_back(include.sourceId);
- }
-
- return topIncludes;
-}
-
-FilePathIds PchCreator::allIncludeIds(const SourceEntries &includes)
-{
- FilePathIds allIncludes;
- allIncludes.reserve(includes.size());
-
- std::transform(includes.begin(),
- includes.end(),
- std::back_inserter(allIncludes),
- [](auto &&entry) { return entry.sourceId; });
-
- return allIncludes;
-}
-
-QByteArray PchCreator::projectPartHash(const V2::ProjectPartContainer &projectPart)
-{
- QCryptographicHash hash(QCryptographicHash::Sha1);
-
- hashProjectPart(hash, projectPart);
-
- auto result = hash.result();
-
- return result.toBase64(QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals);
-}
-
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h
index 34170e2bb5..ce1b7ab1eb 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreator.h
+++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h
@@ -29,12 +29,14 @@
#include "idpaths.h"
#include "sourceentry.h"
+#include "clangtool.h"
#include <filepathcaching.h>
#include <projectpartpch.h>
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
#include <vector>
+#include <random>
QT_FORWARD_DECLARE_CLASS(QFile)
QT_FORWARD_DECLARE_CLASS(QCryptographicHash)
@@ -60,18 +62,13 @@ class PchCreator final : public PchCreatorInterface
public:
PchCreator(Environment &environment,
Sqlite::Database &database,
- PchManagerClientInterface &pchManagerClient,
- ClangPathWatcherInterface &fileSystemWatcher)
- : m_filePathCache(database),
- m_environment(environment),
- m_pchManagerClient(pchManagerClient),
- m_fileSystemWatcher(fileSystemWatcher)
- {
- }
-
- void generatePchDeprecated(const V2::ProjectPartContainer &projectsPart) override;
- void generatePch(const PchTask &pchTask) override;
- IdPaths takeProjectIncludes() override;
+ PchManagerClientInterface &pchManagerClient)
+ : m_filePathCache(database)
+ , m_environment(environment)
+ , m_pchManagerClient(pchManagerClient)
+ {}
+
+ void generatePch(PchTask &&pchTask) override;
const ProjectPartPch &projectPartPch() override;
void setUnsavedFiles(const V2::FileContainers &fileContainers) override;
void setIsUsed(bool isUsed) override;
@@ -79,56 +76,27 @@ public:
void clear() override;
void doInMainThreadAfterFinished() override;
- const IdPaths &projectIncludes() const;
const FilePathCaching &filePathCache();
Utils::SmallString generatePchIncludeFileContent(const FilePathIds &includeIds) const;
- bool generatePch(Utils::SmallStringVector &&commandLineArguments);
-
- static QStringList convertToQStringList(const Utils::SmallStringVector &convertToQStringList);
-
- Utils::SmallStringVector generateProjectPartCommandLine(
- const V2::ProjectPartContainer &projectPart) const;
- Utils::SmallString generateProjectPartPchFilePathWithoutExtension(
- const V2::ProjectPartContainer &projectPart) const;
- Utils::PathStringVector generateProjectPartHeaders(
- const V2::ProjectPartContainer &projectPart) const;
- Utils::SmallString generateProjectPartSourcesContent(
- const V2::ProjectPartContainer &projectPart) const;
- ClangBackEnd::FilePaths generateProjectPartSourcePaths(
- const V2::ProjectPartContainer &projectPart) const;
- SourceEntries generateProjectPartPchIncludes(
- const V2::ProjectPartContainer &projectPart) const;
- Utils::SmallString generateProjectPathPchHeaderFilePath(
- const V2::ProjectPartContainer &projectPart) const;
- Utils::SmallString generateProjectPartPchFilePath(
- const V2::ProjectPartContainer &projectPart) const;
- Utils::SmallString generateProjectPartSourceFilePath(
- const V2::ProjectPartContainer &projectPart) const;
- Utils::SmallStringVector generateProjectPartPchCompilerArguments(
- const V2::ProjectPartContainer &projectPart) const;
- Utils::SmallStringVector generateProjectPartClangCompilerArguments(
- const V2::ProjectPartContainer &projectPart) const;
- IdPaths generateProjectPartPch(
- const V2::ProjectPartContainer &projectPart);
- static std::unique_ptr<QFile> generateFileWithContent(
- const Utils::SmallString &filePath,
- const Utils::SmallString &content);
-
- static FilePathIds topIncludeIds(const SourceEntries &includes);
- static FilePathIds allIncludeIds(const SourceEntries &includes);
+ bool generatePch();
-private:
- static QByteArray projectPartHash(const V2::ProjectPartContainer &projectPart);
+ FilePath generatePchHeaderFilePath() const;
+ FilePath generatePchFilePath() const;
+ static std::vector<std::string> generateClangCompilerArguments(PchTask &&pchTask,
+ FilePathView includePchHeaderPath,
+ FilePathView pchPath);
+ static std::unique_ptr<QFile> generateFileWithContent(const Utils::SmallString &filePath,
+ const Utils::SmallString &content);
private:
+ mutable std::mt19937_64 randomNumberGenator{std::random_device{}()};
+ ClangTool m_clangTool;
ProjectPartPch m_projectPartPch;
- IdPaths m_projectIncludeIds;
FilePathCaching m_filePathCache;
V2::FileContainers m_unsavedFiles;
Environment &m_environment;
PchManagerClientInterface &m_pchManagerClient;
- ClangPathWatcherInterface &m_fileSystemWatcher;
bool m_isUsed = false;
};
diff --git a/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h b/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h
index caa2d67649..dd16e78f59 100644
--- a/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/pchcreatorinterface.h
@@ -31,7 +31,7 @@
#include "processorinterface.h"
#include <filecontainerv2.h>
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
namespace ClangBackEnd {
@@ -42,9 +42,7 @@ public:
PchCreatorInterface(const PchCreatorInterface &) = delete;
PchCreatorInterface &operator=(const PchCreatorInterface &) = delete;
- virtual void generatePchDeprecated(const V2::ProjectPartContainer &projectsPart) = 0;
- virtual void generatePch(const PchTask &pchTask) = 0;
- virtual IdPaths takeProjectIncludes() = 0;
+ virtual void generatePch(PchTask &&pchTask) = 0;
virtual const ProjectPartPch &projectPartPch() = 0;
protected:
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
index 0bc5c10879..2f53560632 100644
--- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.cpp
@@ -28,7 +28,7 @@
#include <pchmanagerclientinterface.h>
#include <precompiledheadersupdatedmessage.h>
#include <progressmessage.h>
-#include <projectpartqueue.h>
+#include <pchtaskgeneratorinterface.h>
#include <removegeneratedfilesmessage.h>
#include <removeprojectpartsmessage.h>
#include <updategeneratedfilesmessage.h>
@@ -41,11 +41,11 @@
namespace ClangBackEnd {
PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
- ProjectPartQueueInterface &projectPartQueue,
+ PchTaskGeneratorInterface &pchTaskGenerator,
ProjectPartsInterface &projectParts,
GeneratedFilesInterface &generatedFiles)
: m_fileSystemWatcher(fileSystemWatcher),
- m_projectPartQueue(projectPartQueue),
+ m_pchTaskGenerator(pchTaskGenerator),
m_projectParts(projectParts),
m_generatedFiles(generatedFiles)
{
@@ -55,12 +55,14 @@ PchManagerServer::PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
void PchManagerServer::end()
{
QCoreApplication::exit();
-
}
void PchManagerServer::updateProjectParts(UpdateProjectPartsMessage &&message)
{
- m_projectPartQueue.addProjectParts(m_projectParts.update(message.takeProjectsParts()));
+ m_toolChainsArgumentsCache.update(message.projectsParts, message.toolChainArguments);
+
+ m_pchTaskGenerator.addProjectParts(
+ m_projectParts.update(message.takeProjectsParts()), std::move(message.toolChainArguments));
}
void PchManagerServer::removeProjectParts(RemoveProjectPartsMessage &&message)
@@ -69,7 +71,9 @@ void PchManagerServer::removeProjectParts(RemoveProjectPartsMessage &&message)
m_projectParts.remove(message.projectsPartIds);
- m_projectPartQueue.removeProjectParts(message.projectsPartIds);
+ m_pchTaskGenerator.removeProjectParts(message.projectsPartIds);
+
+ m_toolChainsArgumentsCache.remove(message.projectsPartIds);
}
void PchManagerServer::updateGeneratedFiles(UpdateGeneratedFilesMessage &&message)
@@ -84,7 +88,12 @@ void PchManagerServer::removeGeneratedFiles(RemoveGeneratedFilesMessage &&messag
void PchManagerServer::pathsWithIdsChanged(const Utils::SmallStringVector &ids)
{
- m_projectPartQueue.addProjectParts(m_projectParts.projects(ids));
+ ArgumentsEntries entries = m_toolChainsArgumentsCache.arguments(ids);
+
+ for (ArgumentsEntry &entry : entries) {
+ m_pchTaskGenerator.addProjectParts(
+ m_projectParts.projects(entry.ids), std::move(entry.arguments));
+ }
}
void PchManagerServer::pathsChanged(const FilePathIds &/*filePathIds*/)
diff --git a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
index b3ff135f52..0c4bd0cc66 100644
--- a/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
+++ b/src/tools/clangpchmanagerbackend/source/pchmanagerserver.h
@@ -30,6 +30,7 @@
#include "pchcreatorinterface.h"
#include "pchmanagerserverinterface.h"
#include "projectpartsinterface.h"
+#include "toolchainargumentscache.h"
#include <generatedfilesinterface.h>
#include <ipcclientprovider.h>
@@ -37,7 +38,7 @@
namespace ClangBackEnd {
class SourceRangesAndDiagnosticsForQueryMessage;
-class ProjectPartQueueInterface;
+class PchTaskGeneratorInterface;
class PchManagerServer : public PchManagerServerInterface,
public ClangPathWatcherNotifier,
@@ -46,7 +47,7 @@ class PchManagerServer : public PchManagerServerInterface,
{
public:
PchManagerServer(ClangPathWatcherInterface &fileSystemWatcher,
- ProjectPartQueueInterface &projectPartQueue,
+ PchTaskGeneratorInterface &pchTaskGenerator,
ProjectPartsInterface &projectParts,
GeneratedFilesInterface &generatedFiles);
@@ -63,9 +64,10 @@ public:
private:
ClangPathWatcherInterface &m_fileSystemWatcher;
- ProjectPartQueueInterface &m_projectPartQueue;
+ PchTaskGeneratorInterface &m_pchTaskGenerator;
ProjectPartsInterface &m_projectParts;
GeneratedFilesInterface &m_generatedFiles;
+ ToolChainsArgumentsCache m_toolChainsArgumentsCache;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchtask.h b/src/tools/clangpchmanagerbackend/source/pchtask.h
index a78b199215..071cbfcb6b 100644
--- a/src/tools/clangpchmanagerbackend/source/pchtask.h
+++ b/src/tools/clangpchmanagerbackend/source/pchtask.h
@@ -28,8 +28,11 @@
#include "builddependency.h"
#include <compilermacro.h>
+#include <filepath.h>
+#include <includesearchpath.h>
#include <utils/smallstringvector.h>
+#include <utils/cpplanguage_details.h>
namespace ClangBackEnd {
@@ -39,21 +42,45 @@ public:
PchTask(Utils::SmallString &&projectPartId,
FilePathIds &&includes,
CompilerMacros &&compilerMacros,
- UsedMacros &&usedMacros)
+ UsedMacros &&usedMacros,
+ Utils::SmallStringVector toolChainArguments,
+ IncludeSearchPaths systemIncludeSearchPaths,
+ IncludeSearchPaths projectIncludeSearchPaths,
+ Utils::Language language = Utils::Language::Cxx,
+ Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX98,
+ Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None)
: projectPartIds({projectPartId})
, includes(includes)
, compilerMacros(compilerMacros)
, usedMacros(usedMacros)
+ , systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
+ , projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
+ , toolChainArguments(std::move(toolChainArguments))
+ , language(language)
+ , languageVersion(languageVersion)
+ , languageExtension(languageExtension)
{}
PchTask(Utils::SmallStringVector &&projectPartIds,
FilePathIds &&includes,
CompilerMacros &&compilerMacros,
- UsedMacros &&usedMacros)
+ UsedMacros &&usedMacros,
+ Utils::SmallStringVector toolChainArguments,
+ IncludeSearchPaths systemIncludeSearchPaths,
+ IncludeSearchPaths projectIncludeSearchPaths,
+ Utils::Language language = Utils::Language::Cxx,
+ Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX98,
+ Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None)
: projectPartIds(std::move(projectPartIds))
, includes(includes)
, compilerMacros(compilerMacros)
, usedMacros(usedMacros)
+ , systemIncludeSearchPaths(std::move(systemIncludeSearchPaths))
+ , projectIncludeSearchPaths(std::move(projectIncludeSearchPaths))
+ , toolChainArguments(std::move(toolChainArguments))
+ , language(language)
+ , languageVersion(languageVersion)
+ , languageExtension(languageExtension)
{}
friend bool operator==(const PchTask &first, const PchTask &second)
@@ -61,17 +88,29 @@ public:
return first.systemPchPath == second.systemPchPath
&& first.projectPartIds == second.projectPartIds && first.includes == second.includes
&& first.compilerMacros == second.compilerMacros
- && first.usedMacros == second.usedMacros;
+ && first.usedMacros == second.usedMacros
+ && first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
+ && first.projectIncludeSearchPaths == second.projectIncludeSearchPaths
+ && first.toolChainArguments == second.toolChainArguments
+ && first.language == second.language
+ && first.languageVersion == second.languageVersion
+ && first.languageExtension == second.languageExtension;
}
Utils::SmallStringView projectPartId() const { return projectPartIds.front(); }
public:
- Utils::PathString systemPchPath;
+ FilePath systemPchPath;
Utils::SmallStringVector projectPartIds;
FilePathIds includes;
CompilerMacros compilerMacros;
UsedMacros usedMacros;
+ IncludeSearchPaths systemIncludeSearchPaths;
+ IncludeSearchPaths projectIncludeSearchPaths;
+ Utils::SmallStringVector toolChainArguments;
+ Utils::Language language = Utils::Language::Cxx;
+ Utils::LanguageVersion languageVersion = Utils::LanguageVersion::CXX98;
+ Utils::LanguageExtension languageExtension = Utils::LanguageExtension::None;
};
class PchTaskSet
diff --git a/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp b/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp
index 37311aa238..8159dbeb12 100644
--- a/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.cpp
@@ -34,7 +34,8 @@
namespace ClangBackEnd {
-void PchTaskGenerator::create(V2::ProjectPartContainers &&projectParts)
+void PchTaskGenerator::addProjectParts(ProjectPartContainers &&projectParts,
+ Utils::SmallStringVector &&toolChainArguments)
{
PchTaskSets pchTaskSets;
pchTaskSets.reserve(projectParts.size());
@@ -46,18 +47,33 @@ void PchTaskGenerator::create(V2::ProjectPartContainers &&projectParts)
filter.filter(projectPart.compilerMacros);
pchTaskSets.emplace_back(PchTask{projectPart.projectPartId.clone(),
- std::move(filter.systemIncludes),
+ std::move(filter.topSystemIncludes),
std::move(filter.systemCompilerMacros),
- std::move(filter.systemUsedMacros)
-
- },
+ std::move(filter.systemUsedMacros),
+ projectPart.toolChainArguments,
+ projectPart.systemIncludeSearchPaths,
+ projectPart.projectIncludeSearchPaths,
+ projectPart.language,
+ projectPart.languageVersion,
+ projectPart.languageExtension},
PchTask{std::move(projectPart.projectPartId),
- std::move(filter.projectIncludes),
+ std::move(filter.topProjectIncludes),
std::move(filter.projectCompilerMacros),
- std::move(filter.projectUsedMacros)});
+ std::move(filter.projectUsedMacros),
+ projectPart.toolChainArguments,
+ projectPart.systemIncludeSearchPaths,
+ projectPart.projectIncludeSearchPaths,
+ projectPart.language,
+ projectPart.languageVersion,
+ projectPart.languageExtension});
}
- m_pchTasksMergerInterface.mergeTasks(std::move(pchTaskSets));
+ m_pchTasksMergerInterface.mergeTasks(std::move(pchTaskSets), std::move(toolChainArguments));
+}
+
+void PchTaskGenerator::removeProjectParts(const Utils::SmallStringVector &projectsPartIds)
+{
+ m_pchTasksMergerInterface.removePchTasks(projectsPartIds);
}
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.h b/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.h
index d7a7937d80..b5669b7b3f 100644
--- a/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.h
+++ b/src/tools/clangpchmanagerbackend/source/pchtaskgenerator.h
@@ -26,8 +26,9 @@
#pragma once
#include "pchtask.h"
+#include "pchtaskgeneratorinterface.h"
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
namespace ClangBackEnd {
@@ -35,7 +36,7 @@ class PchTasksMergerInterface;
class BuildDependenciesProviderInterface;
-class PchTaskGenerator
+class PchTaskGenerator : public PchTaskGeneratorInterface
{
public:
PchTaskGenerator(BuildDependenciesProviderInterface &buildDependenciesProvider,
@@ -44,7 +45,9 @@ public:
, m_pchTasksMergerInterface(pchTasksMergerInterface)
{}
- void create(V2::ProjectPartContainers &&projectParts);
+ void addProjectParts(ProjectPartContainers &&projectParts,
+ Utils::SmallStringVector &&toolChainArguments);
+ void removeProjectParts(const Utils::SmallStringVector &projectsPartIds);
private:
BuildDependenciesProviderInterface &m_buildDependenciesProvider;
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartqueueinterface.h b/src/tools/clangpchmanagerbackend/source/pchtaskgeneratorinterface.h
index 0b705fe312..4546284265 100644
--- a/src/tools/clangpchmanagerbackend/source/projectpartqueueinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/pchtaskgeneratorinterface.h
@@ -25,19 +25,20 @@
#pragma once
-#include "queueinterface.h"
-
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
namespace ClangBackEnd {
-class ProjectPartQueueInterface : public QueueInterface
+class PchTaskGeneratorInterface
{
public:
- virtual void addProjectParts(V2::ProjectPartContainers &&projectParts) = 0;
+ virtual void addProjectParts(ProjectPartContainers &&projectParts,
+ Utils::SmallStringVector &&toolChainArguments)
+ = 0;
virtual void removeProjectParts(const Utils::SmallStringVector &projectsPartIds) = 0;
protected:
- ~ProjectPartQueueInterface() = default;
+ ~PchTaskGeneratorInterface() = default;
};
+
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp b/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp
index 6b82290ef1..6c1a09fd3e 100644
--- a/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp
@@ -52,8 +52,6 @@ void PchTaskQueue::addPchTasks(PchTasks &&newPchTasks, PchTasks &destination)
destination = std::move(mergedPchTasks);
m_progressCounter.addTotal(int(destination.size() - oldSize));
-
- processEntries();
}
void PchTaskQueue::removePchTasksByProjectPartId(const Utils::SmallStringVector &projectsPartIds,
@@ -143,22 +141,17 @@ std::vector<PchTaskQueue::Task> PchTaskQueue::createProjectTasks(PchTasks &&pchT
auto convert = [this](auto &&pchTask) {
return [pchTask = std::move(pchTask), this](PchCreatorInterface &pchCreator) mutable {
- Sqlite::DeferredTransaction readTransaction(m_transactionsInterface);
+ const auto projectPartId = pchTask.projectPartId();
pchTask.systemPchPath = m_precompiledHeaderStorage.fetchSystemPrecompiledHeaderPath(
- pchTask.projectPartId());
- readTransaction.commit();
- pchCreator.generatePch(pchTask);
+ projectPartId);
+ pchCreator.generatePch(std::move(pchTask));
const auto &projectPartPch = pchCreator.projectPartPch();
- Sqlite::ImmediateTransaction writeTransaction(m_transactionsInterface);
if (projectPartPch.pchPath.empty()) {
- m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(pchTask.projectPartId());
+ m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(projectPartId);
} else {
- m_precompiledHeaderStorage
- .insertProjectPrecompiledHeader(pchTask.projectPartId(),
- projectPartPch.pchPath,
- projectPartPch.lastModified);
+ m_precompiledHeaderStorage.insertProjectPrecompiledHeader(
+ projectPartId, projectPartPch.pchPath, projectPartPch.lastModified);
}
- writeTransaction.commit();
};
};
@@ -176,21 +169,17 @@ std::vector<PchTaskQueue::Task> PchTaskQueue::createSystemTasks(PchTasks &&pchTa
tasks.reserve(pchTasks.size());
auto convert = [this](auto &&pchTask) {
- return [pchTask = std::move(pchTask), this](PchCreatorInterface &pchCreator) {
- pchCreator.generatePch(pchTask);
+ return [pchTask = std::move(pchTask), this](PchCreatorInterface &pchCreator) mutable {
+ const auto projectPartIds = pchTask.projectPartIds;
+ pchCreator.generatePch(std::move(pchTask));
const auto &projectPartPch = pchCreator.projectPartPch();
- Sqlite::ImmediateTransaction transaction(m_transactionsInterface);
- for (Utils::SmallStringView projectPartId : pchTask.projectPartIds) {
- if (projectPartPch.pchPath.empty()) {
- m_precompiledHeaderStorage.deleteSystemPrecompiledHeader(projectPartId);
- } else {
- m_precompiledHeaderStorage
- .insertSystemPrecompiledHeader(projectPartId,
- projectPartPch.pchPath,
- projectPartPch.lastModified);
- }
+ if (projectPartPch.pchPath.empty()) {
+ m_precompiledHeaderStorage.deleteSystemPrecompiledHeaders(projectPartIds);
+ } else {
+ m_precompiledHeaderStorage.insertSystemPrecompiledHeaders(projectPartIds,
+ projectPartPch.pchPath,
+ projectPartPch.lastModified);
}
- transaction.commit();
};
};
diff --git a/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp b/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp
index a241c60764..9ace04e09d 100644
--- a/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp
+++ b/src/tools/clangpchmanagerbackend/source/pchtasksmerger.cpp
@@ -29,7 +29,8 @@
namespace ClangBackEnd {
-void PchTasksMerger::mergeTasks(PchTaskSets &&taskSets)
+void PchTasksMerger::mergeTasks(PchTaskSets &&taskSets,
+ Utils::SmallStringVector &&/*toolChainArguments*/)
{
PchTasks systemTasks;
systemTasks.reserve(taskSets.size());
@@ -46,4 +47,9 @@ void PchTasksMerger::mergeTasks(PchTaskSets &&taskSets)
m_pchTaskQueue.processEntries();
}
+void PchTasksMerger::removePchTasks(const Utils::SmallStringVector &projectPartIds)
+{
+ m_pchTaskQueue.removePchTasks(projectPartIds);
+}
+
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/pchtasksmerger.h b/src/tools/clangpchmanagerbackend/source/pchtasksmerger.h
index 97bed64e99..9c777b8a7c 100644
--- a/src/tools/clangpchmanagerbackend/source/pchtasksmerger.h
+++ b/src/tools/clangpchmanagerbackend/source/pchtasksmerger.h
@@ -39,7 +39,8 @@ public:
: m_pchTaskQueue(pchTaskQueue)
{}
- void mergeTasks(PchTaskSets &&taskSets) override;
+ void mergeTasks(PchTaskSets &&taskSets, Utils::SmallStringVector &&toolChainArguments) override;
+ void removePchTasks(const Utils::SmallStringVector &projectPartIds) override;
private:
PchTaskQueueInterface &m_pchTaskQueue;
diff --git a/src/tools/clangpchmanagerbackend/source/pchtasksmergerinterface.h b/src/tools/clangpchmanagerbackend/source/pchtasksmergerinterface.h
index 4fe96581bc..a691766b49 100644
--- a/src/tools/clangpchmanagerbackend/source/pchtasksmergerinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/pchtasksmergerinterface.h
@@ -31,7 +31,8 @@ namespace ClangBackEnd {
class PchTasksMergerInterface
{
public:
- virtual void mergeTasks(PchTaskSets &&taskSets) = 0;
+ virtual void mergeTasks(PchTaskSets &&taskSets, Utils::SmallStringVector &&toolChainArguments) = 0;
+ virtual void removePchTasks(const Utils::SmallStringVector &projectPartIds) = 0;
protected:
~PchTasksMergerInterface() = default;
diff --git a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h
index 67ee9b4fe6..022f5d926b 100644
--- a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h
+++ b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorage.h
@@ -48,8 +48,8 @@ public:
}
void insertProjectPrecompiledHeader(Utils::SmallStringView projectPartName,
- Utils::SmallStringView pchPath,
- long long pchBuildTime) override
+ Utils::SmallStringView pchPath,
+ long long pchBuildTime) override
{
try {
Sqlite::ImmediateTransaction transaction{m_database};
@@ -76,42 +76,44 @@ public:
}
}
- void insertSystemPrecompiledHeader(Utils::SmallStringView projectPartName,
- Utils::SmallStringView pchPath,
- long long pchBuildTime) override
+ void insertSystemPrecompiledHeaders(const Utils::SmallStringVector &projectPartNames,
+ Utils::SmallStringView pchPath,
+ long long pchBuildTime) override
{
try {
Sqlite::ImmediateTransaction transaction{m_database};
- m_insertProjectPartStatement.write(projectPartName);
- m_insertSystemPrecompiledHeaderStatement.write(projectPartName, pchPath, pchBuildTime);
-
+ for (Utils::SmallStringView projectPartName : projectPartNames) {
+ m_insertProjectPartStatement.write(projectPartName);
+ m_insertSystemPrecompiledHeaderStatement.write(projectPartName, pchPath, pchBuildTime);
+ }
transaction.commit();
} catch (const Sqlite::StatementIsBusy) {
- insertSystemPrecompiledHeader(projectPartName, pchPath, pchBuildTime);
+ insertSystemPrecompiledHeaders(projectPartNames, pchPath, pchBuildTime);
}
}
- void deleteSystemPrecompiledHeader(Utils::SmallStringView projectPartName) override
+ void deleteSystemPrecompiledHeaders(const Utils::SmallStringVector &projectPartNames) override
{
try {
Sqlite::ImmediateTransaction transaction{m_database};
- m_deleteSystemPrecompiledHeaderStatement.write(projectPartName);
+ for (Utils::SmallStringView projectPartName : projectPartNames)
+ m_deleteSystemPrecompiledHeaderStatement.write(projectPartName);
transaction.commit();
} catch (const Sqlite::StatementIsBusy) {
- deleteSystemPrecompiledHeader(projectPartName);
+ deleteSystemPrecompiledHeaders(projectPartNames);
}
}
- Utils::PathString fetchSystemPrecompiledHeaderPath(Utils::SmallStringView projectPartName) override
+ FilePath fetchSystemPrecompiledHeaderPath(Utils::SmallStringView projectPartName) override
{
try {
Sqlite::DeferredTransaction transaction{m_database};
- auto value = m_fetchSystemPrecompiledHeaderPathStatement
- .template value<Utils::PathString>(projectPartName);
+ auto value = m_fetchSystemPrecompiledHeaderPathStatement.template value<FilePath>(
+ projectPartName);
if (value)
return value.value();
@@ -121,7 +123,7 @@ public:
return fetchSystemPrecompiledHeaderPath(projectPartName);
}
- return Utils::SmallStringView("");
+ return FilePath("");
}
public:
diff --git a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h
index 2ade4e885a..2a7e11604b 100644
--- a/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/precompiledheaderstorageinterface.h
@@ -25,7 +25,9 @@
#pragma once
-#include <utils/smallstring.h>
+#include <filepath.h>
+
+#include <utils/smallstringvector.h>
namespace ClangBackEnd {
@@ -42,13 +44,12 @@ public:
long long pchBuildTime)
= 0;
virtual void deleteProjectPrecompiledHeader(Utils::SmallStringView projectPartName) = 0;
- virtual void insertSystemPrecompiledHeader(Utils::SmallStringView projectPartName,
- Utils::SmallStringView pchPath,
- long long pchBuildTime)
+ virtual void insertSystemPrecompiledHeaders(const Utils::SmallStringVector &projectPartNames,
+ Utils::SmallStringView pchPath,
+ long long pchBuildTime)
= 0;
- virtual void deleteSystemPrecompiledHeader(Utils::SmallStringView projectPartName) = 0;
- virtual Utils::PathString fetchSystemPrecompiledHeaderPath(
- Utils::SmallStringView projectPartName) = 0;
+ virtual void deleteSystemPrecompiledHeaders(const Utils::SmallStringVector &projectPartNames) = 0;
+ virtual FilePath fetchSystemPrecompiledHeaderPath(Utils::SmallStringView projectPartName) = 0;
protected:
~PrecompiledHeaderStorageInterface() = default;
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartqueue.cpp b/src/tools/clangpchmanagerbackend/source/projectpartqueue.cpp
deleted file mode 100644
index 48f133f7d7..0000000000
--- a/src/tools/clangpchmanagerbackend/source/projectpartqueue.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "projectpartqueue.h"
-
-#include <pchcreatorinterface.h>
-#include <precompiledheaderstorageinterface.h>
-#include <progresscounter.h>
-#include <sqlitetransaction.h>
-
-namespace ClangBackEnd {
-
-void ProjectPartQueue::addProjectParts(V2::ProjectPartContainers &&projectParts)
-{
- auto compare = [](const V2::ProjectPartContainer &first, const V2::ProjectPartContainer &second) {
- return first.projectPartId < second.projectPartId;
- };
-
- const std::size_t oldSize = m_projectParts.size();
-
- V2::ProjectPartContainers mergedProjectParts;
- mergedProjectParts.reserve(m_projectParts.size() + projectParts.size());
- std::set_union(std::make_move_iterator(projectParts.begin()),
- std::make_move_iterator(projectParts.end()),
- std::make_move_iterator(m_projectParts.begin()),
- std::make_move_iterator(m_projectParts.end()),
- std::back_inserter(mergedProjectParts),
- compare);
-
- m_projectParts = std::move(mergedProjectParts);
-
- m_progressCounter.addTotal(int(m_projectParts.size() - oldSize));
-
- processEntries();
-}
-
-class CompareDifference
-{
-public:
- bool operator()(const V2::ProjectPartContainer &first, const Utils::SmallString &second)
- {
- return first.projectPartId < second;
- }
-
- bool operator()(const Utils::SmallString &first, const V2::ProjectPartContainer &second)
- {
- return first < second.projectPartId;
- }
-};
-
-void ProjectPartQueue::removeProjectParts(const Utils::SmallStringVector &projectsPartIds)
-{
- const std::size_t oldSize = m_projectParts.size();
-
- V2::ProjectPartContainers notToBeRemovedProjectParts;
- notToBeRemovedProjectParts.reserve(m_projectParts.size());
- std::set_difference(std::make_move_iterator(m_projectParts.begin()),
- std::make_move_iterator(m_projectParts.end()),
- projectsPartIds.begin(),
- projectsPartIds.end(),
- std::back_inserter(notToBeRemovedProjectParts),
- CompareDifference{});
-
- m_projectParts = std::move(notToBeRemovedProjectParts);
-
- m_progressCounter.removeTotal(int(oldSize - m_projectParts.size()));
-}
-
-void ProjectPartQueue::processEntries()
-{
- uint taskCount = m_taskScheduler.slotUsage().free;
-
- auto newEnd = std::prev(m_projectParts.end(), std::min<int>(int(taskCount), int(m_projectParts.size())));
- m_taskScheduler.addTasks(
- createPchTasks({std::make_move_iterator(newEnd),
- std::make_move_iterator(m_projectParts.end())}));
- m_projectParts.erase(newEnd, m_projectParts.end());
-}
-
-const V2::ProjectPartContainers &ProjectPartQueue::projectParts() const
-{
- return m_projectParts;
-}
-
-std::vector<ProjectPartQueue::Task> ProjectPartQueue::createPchTasks(
- V2::ProjectPartContainers &&projectParts) const
-{
- std::vector<Task> tasks;
- tasks.reserve(projectParts.size());
-
- auto convert = [this] (auto &&projectPart) {
- return [projectPart=std::move(projectPart), this] (PchCreatorInterface &pchCreator) {
- pchCreator.generatePchDeprecated(projectPart);
- const auto &projectPartPch = pchCreator.projectPartPch();
- Sqlite::ImmediateTransaction transaction(m_transactionsInterface);
- if (projectPartPch.pchPath.empty()) {
- m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(projectPartPch.projectPartId);
- } else {
- m_precompiledHeaderStorage.insertProjectPrecompiledHeader(projectPartPch.projectPartId,
- projectPartPch.pchPath,
- projectPartPch.lastModified);
- }
- transaction.commit();
- };
- };
-
- std::transform(std::make_move_iterator(projectParts.begin()),
- std::make_move_iterator(projectParts.end()),
- std::back_inserter(tasks),
- convert);
-
- return tasks;
-}
-
-} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartqueue.h b/src/tools/clangpchmanagerbackend/source/projectpartqueue.h
deleted file mode 100644
index 9365d7e5cc..0000000000
--- a/src/tools/clangpchmanagerbackend/source/projectpartqueue.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#pragma once
-
-#include "projectpartqueueinterface.h"
-#include "taskschedulerinterface.h"
-
-namespace Sqlite {
-class TransactionInterface;
-}
-
-namespace ClangBackEnd {
-
-class PrecompiledHeaderStorageInterface;
-class ProgressCounter;
-class PchTaskSchedulerInterface;
-class PchCreatorInterface;
-
-class ProjectPartQueue final : public ProjectPartQueueInterface
-{
-public:
- using Task = std::function<void (PchCreatorInterface&)>;
-
- ProjectPartQueue(TaskSchedulerInterface<Task> &taskScheduler,
- PrecompiledHeaderStorageInterface &precompiledHeaderStorage,
- Sqlite::TransactionInterface &transactionsInterface,
- ProgressCounter &progressCounter)
- : m_taskScheduler(taskScheduler),
- m_precompiledHeaderStorage(precompiledHeaderStorage),
- m_transactionsInterface(transactionsInterface),
- m_progressCounter(progressCounter)
- {}
-
- void addProjectParts(V2::ProjectPartContainers &&projectParts);
- void removeProjectParts(const Utils::SmallStringVector &projectsPartIds);
-
- void processEntries();
-
- const V2::ProjectPartContainers &projectParts() const;
-
- std::vector<Task> createPchTasks(V2::ProjectPartContainers &&projectParts) const;
-
-private:
- V2::ProjectPartContainers m_projectParts;
- TaskSchedulerInterface<Task> &m_taskScheduler;
- PrecompiledHeaderStorageInterface &m_precompiledHeaderStorage;
- Sqlite::TransactionInterface &m_transactionsInterface;
- ProgressCounter &m_progressCounter;
-};
-
-} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/projectparts.cpp b/src/tools/clangpchmanagerbackend/source/projectparts.cpp
index 6be06380bf..bf2235fd13 100644
--- a/src/tools/clangpchmanagerbackend/source/projectparts.cpp
+++ b/src/tools/clangpchmanagerbackend/source/projectparts.cpp
@@ -25,7 +25,7 @@
#include "projectparts.h"
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
#include <algorithm>
@@ -33,7 +33,7 @@ namespace ClangBackEnd {
inline namespace Pch {
-V2::ProjectPartContainers ProjectParts::update(V2::ProjectPartContainers &&projectsParts)
+ProjectPartContainers ProjectParts::update(ProjectPartContainers &&projectsParts)
{
auto updatedProjectPartContainers = newProjectParts(std::move(projectsParts));
@@ -44,7 +44,7 @@ V2::ProjectPartContainers ProjectParts::update(V2::ProjectPartContainers &&proje
void ProjectParts::remove(const Utils::SmallStringVector &ids)
{
- auto shouldRemove = [&] (const V2::ProjectPartContainer &projectPart) {
+ auto shouldRemove = [&] (const ProjectPartContainer &projectPart) {
return std::find(ids.begin(), ids.end(), projectPart.projectPartId) != ids.end();
};
@@ -52,23 +52,23 @@ void ProjectParts::remove(const Utils::SmallStringVector &ids)
m_projectParts.erase(newEnd, m_projectParts.end());
}
-V2::ProjectPartContainers ProjectParts::projects(const Utils::SmallStringVector &projectPartIds) const
+ProjectPartContainers ProjectParts::projects(const Utils::SmallStringVector &projectPartIds) const
{
- V2::ProjectPartContainers projectPartsWithIds;
+ ProjectPartContainers projectPartsWithIds;
std::copy_if(m_projectParts.begin(),
m_projectParts.end(),
std::back_inserter(projectPartsWithIds),
- [&] (const V2::ProjectPartContainer &projectPart) {
+ [&] (const ProjectPartContainer &projectPart) {
return std::binary_search(projectPartIds.begin(), projectPartIds.end(), projectPart.projectPartId);
});
return projectPartsWithIds;
}
-V2::ProjectPartContainers ProjectParts::newProjectParts(V2::ProjectPartContainers &&projectsParts) const
+ProjectPartContainers ProjectParts::newProjectParts(ProjectPartContainers &&projectsParts) const
{
- V2::ProjectPartContainers updatedProjectPartContainers;
+ ProjectPartContainers updatedProjectPartContainers;
updatedProjectPartContainers.reserve(projectsParts.size());
std::set_difference(std::make_move_iterator(projectsParts.begin()),
@@ -80,12 +80,12 @@ V2::ProjectPartContainers ProjectParts::newProjectParts(V2::ProjectPartContainer
return updatedProjectPartContainers;
}
-void ProjectParts::mergeProjectParts(const V2::ProjectPartContainers &projectsParts)
+void ProjectParts::mergeProjectParts(const ProjectPartContainers &projectsParts)
{
- V2::ProjectPartContainers newProjectParts;
+ ProjectPartContainers newProjectParts;
newProjectParts.reserve(m_projectParts.size() + projectsParts.size());
- auto compare = [] (const V2::ProjectPartContainer &first, const V2::ProjectPartContainer &second) {
+ auto compare = [] (const ProjectPartContainer &first, const ProjectPartContainer &second) {
return first.projectPartId < second.projectPartId;
};
@@ -99,7 +99,7 @@ void ProjectParts::mergeProjectParts(const V2::ProjectPartContainers &projectsPa
m_projectParts = newProjectParts;
}
-const V2::ProjectPartContainers &ProjectParts::projectParts() const
+const ProjectPartContainers &ProjectParts::projectParts() const
{
return m_projectParts;
}
diff --git a/src/tools/clangpchmanagerbackend/source/projectparts.h b/src/tools/clangpchmanagerbackend/source/projectparts.h
index c0d9c61e7f..dfe03fa037 100644
--- a/src/tools/clangpchmanagerbackend/source/projectparts.h
+++ b/src/tools/clangpchmanagerbackend/source/projectparts.h
@@ -38,17 +38,17 @@ inline namespace Pch {
class ProjectParts final : public ProjectPartsInterface
{
public:
- V2::ProjectPartContainers update(V2::ProjectPartContainers &&projectsParts) override;
+ ProjectPartContainers update(ProjectPartContainers &&projectsParts) override;
void remove(const Utils::SmallStringVector &projectPartIds) override;
- V2::ProjectPartContainers projects(const Utils::SmallStringVector &projectPartIds) const override;
+ ProjectPartContainers projects(const Utils::SmallStringVector &projectPartIds) const override;
unittest_public:
- V2::ProjectPartContainers newProjectParts(V2::ProjectPartContainers &&projectsParts) const;
- void mergeProjectParts(const V2::ProjectPartContainers &projectsParts);
- const V2::ProjectPartContainers &projectParts() const;
+ ProjectPartContainers newProjectParts(ProjectPartContainers &&projectsParts) const;
+ void mergeProjectParts(const ProjectPartContainers &projectsParts);
+ const ProjectPartContainers &projectParts() const;
private:
- V2::ProjectPartContainers m_projectParts;
+ ProjectPartContainers m_projectParts;
};
} // namespace Pch
diff --git a/src/tools/clangpchmanagerbackend/source/projectpartsinterface.h b/src/tools/clangpchmanagerbackend/source/projectpartsinterface.h
index 97d6c5bfc2..f84ad98090 100644
--- a/src/tools/clangpchmanagerbackend/source/projectpartsinterface.h
+++ b/src/tools/clangpchmanagerbackend/source/projectpartsinterface.h
@@ -25,7 +25,7 @@
#pragma once
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
namespace ClangBackEnd {
@@ -36,9 +36,9 @@ public:
ProjectPartsInterface(const ProjectPartsInterface &) = delete;
ProjectPartsInterface &operator=(const ProjectPartsInterface &) = delete;
- virtual V2::ProjectPartContainers update(V2::ProjectPartContainers &&projectsParts) = 0;
+ virtual ProjectPartContainers update(ProjectPartContainers &&projectsParts) = 0;
virtual void remove(const Utils::SmallStringVector &projectPartIds) = 0;
- virtual V2::ProjectPartContainers projects(const Utils::SmallStringVector &projectPartIds) const = 0;
+ virtual ProjectPartContainers projects(const Utils::SmallStringVector &projectPartIds) const = 0;
protected:
~ProjectPartsInterface() = default;
diff --git a/src/tools/clangpchmanagerbackend/source/sourceentry.h b/src/tools/clangpchmanagerbackend/source/sourceentry.h
index 3cc0fb455a..e903baf3f6 100644
--- a/src/tools/clangpchmanagerbackend/source/sourceentry.h
+++ b/src/tools/clangpchmanagerbackend/source/sourceentry.h
@@ -56,41 +56,81 @@ public:
int64 value = -1;
};
-class SourceEntry
+class SourceTimeStamp
{
+protected:
using int64 = long long;
public:
+ SourceTimeStamp(int sourceId, int64 lastModified)
+ : lastModified(lastModified)
+ , sourceId(sourceId)
+ {}
+
+ SourceTimeStamp(FilePathId sourceId, TimeStamp lastModified)
+ : lastModified(lastModified)
+ , sourceId(sourceId)
+ {}
+
+ friend bool operator<(SourceTimeStamp first, SourceTimeStamp second)
+ {
+ return first.sourceId < second.sourceId;
+ }
+
+ friend bool operator<(SourceTimeStamp first, FilePathId second)
+ {
+ return first.sourceId < second;
+ }
+
+ friend bool operator<(FilePathId first, SourceTimeStamp second)
+ {
+ return first < second.sourceId;
+ }
+
+ friend bool operator==(SourceTimeStamp first, SourceTimeStamp second)
+ {
+ return first.sourceId == second.sourceId && first.lastModified == second.lastModified;
+ }
+
+ friend bool operator!=(SourceTimeStamp first, SourceTimeStamp second)
+ {
+ return !(first == second);
+ }
+
+public:
+ TimeStamp lastModified;
+ FilePathId sourceId;
+};
+
+using SourceTimeStamps = std::vector<SourceTimeStamp>;
+
+class SourceEntry : public SourceTimeStamp
+{
+
+public:
SourceEntry(int sourceId, int64 lastModified, int sourceType)
- : lastModified(lastModified),
- sourceId(sourceId),
- sourceType(static_cast<SourceType>(sourceType))
+ : SourceTimeStamp(sourceId, lastModified)
+ , sourceType(static_cast<SourceType>(sourceType))
{}
SourceEntry(FilePathId sourceId, SourceType sourceType, TimeStamp lastModified)
- : lastModified(lastModified),
- sourceId(sourceId),
- sourceType(sourceType)
+ : SourceTimeStamp(sourceId, lastModified)
+ , sourceType(sourceType)
{}
- friend
- bool operator<(SourceEntry first, SourceEntry second)
+ friend bool operator<(SourceEntry first, SourceEntry second)
{
return first.sourceId < second.sourceId;
}
- friend
- bool operator==(SourceEntry first, SourceEntry second)
+ friend bool operator==(SourceEntry first, SourceEntry second)
{
- return first.sourceId == second.sourceId
- && first.sourceType == second.sourceType
- && first.lastModified == second.lastModified ;
+ return first.sourceId == second.sourceId && first.sourceType == second.sourceType
+ && first.lastModified == second.lastModified;
}
friend bool operator!=(SourceEntry first, SourceEntry second) { return !(first == second); }
public:
- TimeStamp lastModified;
- FilePathId sourceId;
SourceType sourceType = SourceType::UserInclude;
};
diff --git a/src/tools/clangpchmanagerbackend/source/taskscheduler.h b/src/tools/clangpchmanagerbackend/source/taskscheduler.h
index e2891a1163..621baef090 100644
--- a/src/tools/clangpchmanagerbackend/source/taskscheduler.h
+++ b/src/tools/clangpchmanagerbackend/source/taskscheduler.h
@@ -56,6 +56,8 @@ class ProcessorManagerInterface;
class QueueInterface;
class SymbolStorageInterface;
+enum class CallDoInMainThreadAfterFinished : char { Yes, No };
+
template <typename ProcessorManager,
typename Task>
class TaskScheduler : public TaskSchedulerInterface<Task>
@@ -68,23 +70,22 @@ public:
QueueInterface &queue,
ProgressCounter &progressCounter,
uint hardwareConcurrency,
+ CallDoInMainThreadAfterFinished callDoInMainThreadAfterFinished,
std::launch launchPolicy = std::launch::async)
- : m_processorManager(processorManager),
- m_queue(queue),
- m_progressCounter(progressCounter),
- m_hardwareConcurrency(hardwareConcurrency),
- m_launchPolicy(launchPolicy)
+ : m_processorManager(processorManager)
+ , m_queue(queue)
+ , m_progressCounter(progressCounter)
+ , m_hardwareConcurrency(hardwareConcurrency)
+ , m_launchPolicy(launchPolicy)
+ , m_callDoInMainThreadAfterFinished(callDoInMainThreadAfterFinished)
{}
void addTasks(std::vector<Task> &&tasks)
{
for (auto &task : tasks) {
- auto callWrapper = [&, task=std::move(task)] (auto processor)
- -> ProcessorInterface& {
+ auto callWrapper = [&, task = std::move(task)](auto processor) -> ProcessorInterface & {
task(processor.get());
- executeInLoop([&] {
- m_queue.processEntries();
- });
+ executeInLoop([&] { m_queue.processEntries(); });
return processor;
};
@@ -130,9 +131,10 @@ private:
auto split = std::partition(m_futures.begin(), m_futures.end(), notReady);
- std::for_each(split, m_futures.end(), [] (Future &future) {
+ std::for_each(split, m_futures.end(), [&] (Future &future) {
ProcessorInterface &processor = future.get();
- processor.doInMainThreadAfterFinished();
+ if (m_callDoInMainThreadAfterFinished == CallDoInMainThreadAfterFinished::Yes)
+ processor.doInMainThreadAfterFinished();
processor.setIsUsed(false);
processor.clear();
});
@@ -191,6 +193,7 @@ private:
uint m_hardwareConcurrency;
std::launch m_launchPolicy;
bool m_isDisabled = false;
+ CallDoInMainThreadAfterFinished m_callDoInMainThreadAfterFinished;
};
} // namespace ClangBackEnd
diff --git a/src/tools/clangpchmanagerbackend/source/toolchainargumentscache.h b/src/tools/clangpchmanagerbackend/source/toolchainargumentscache.h
new file mode 100644
index 0000000000..4921b29a21
--- /dev/null
+++ b/src/tools/clangpchmanagerbackend/source/toolchainargumentscache.h
@@ -0,0 +1,187 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include <projectpartcontainer.h>
+
+#include <functional>
+
+namespace ClangBackEnd {
+
+struct ArgumentsEntry
+{
+ ArgumentsEntry(Utils::SmallStringVector &&ids, const Utils::SmallStringVector &arguments)
+ : ids(std::move(ids))
+ , arguments(arguments)
+ {}
+
+ ArgumentsEntry(const Utils::SmallStringVector &ids, const Utils::SmallStringVector &arguments)
+ : ids(ids)
+ , arguments(arguments)
+ {}
+
+ void mergeIds(Utils::SmallStringVector &&newIds)
+ {
+ Utils::SmallStringVector mergedIds;
+ mergedIds.reserve(ids.size() + newIds.size());
+
+ std::set_union(std::make_move_iterator(ids.begin()),
+ std::make_move_iterator(ids.end()),
+ std::make_move_iterator(newIds.begin()),
+ std::make_move_iterator(newIds.end()),
+ std::back_inserter(mergedIds));
+
+ ids = mergedIds;
+ }
+
+ void removeIds(const Utils::SmallStringVector &idsToBeRemoved)
+ {
+ Utils::SmallStringVector idsWithout;
+ idsWithout.reserve(ids.size());
+ std::set_difference(std::make_move_iterator(ids.begin()),
+ std::make_move_iterator(ids.end()),
+ idsToBeRemoved.begin(),
+ idsToBeRemoved.end(),
+ std::back_inserter(idsWithout));
+
+ ids = idsWithout;
+ }
+
+ Utils::SmallStringVector ids;
+ Utils::SmallStringVector arguments;
+};
+
+using ArgumentsEntries = std::vector<ArgumentsEntry>;
+
+class ToolChainsArgumentsCache
+{
+public:
+ void update(const ProjectPartContainers &projectParts,
+ const Utils::SmallStringVector &arguments)
+ {
+ struct Compare
+ {
+ bool operator()(const ArgumentsEntry &entry, const Utils::SmallStringVector &arguments)
+ {
+ return entry.arguments < arguments;
+ }
+
+ bool operator()(const Utils::SmallStringVector &arguments, const ArgumentsEntry &entry)
+ {
+ return arguments < entry.arguments;
+ }
+ };
+
+ auto found = std::lower_bound(m_argumentEntries.begin(),
+ m_argumentEntries.end(),
+ arguments,
+ Compare{});
+
+ if (found != m_argumentEntries.end() && found->arguments == arguments) {
+ auto ids = createIds(projectParts);
+ auto removeIds = [&] (ArgumentsEntry &entry) {
+ entry.removeIds(ids);
+ };
+ std::for_each(m_argumentEntries.begin(), found, removeIds);
+ std::for_each(std::next(found), m_argumentEntries.end(), removeIds);
+ found->mergeIds(std::move(ids));
+ } else {
+ auto ids = createIds(projectParts);
+ for (ArgumentsEntry &entry : m_argumentEntries)
+ entry.removeIds(ids);
+ found = m_argumentEntries.emplace(found, std::move(ids), arguments);
+ }
+
+ removeEmptyEntries();
+ }
+
+ void remove(const Utils::SmallStringVector &idsToBeRemoved)
+ {
+ ArgumentsEntries entries;
+ for (ArgumentsEntry &entry : m_argumentEntries) {
+ Utils::SmallStringVector usedIds;
+ std::set_difference(entry.ids.begin(),
+ entry.ids.end(),
+ idsToBeRemoved.begin(),
+ idsToBeRemoved.end(),
+ std::back_inserter(usedIds));
+
+ entry.ids = std::move(usedIds);
+ }
+
+ removeEmptyEntries();
+ }
+
+ ArgumentsEntries arguments(const Utils::SmallStringVector &ids) const
+ {
+ ArgumentsEntries entries;
+ for (const ArgumentsEntry &entry : m_argumentEntries) {
+ Utils::SmallStringVector usedIds;
+ std::set_intersection(entry.ids.begin(),
+ entry.ids.end(),
+ ids.begin(),
+ ids.end(),
+ std::back_inserter(usedIds));
+
+ if (!usedIds.empty())
+ entries.emplace_back(usedIds, entry.arguments);
+ }
+
+ return entries;
+ }
+
+ std::size_t size() const
+ {
+ return m_argumentEntries.size();
+ }
+
+private:
+ static Utils::SmallStringVector createIds(const ProjectPartContainers &projectParts)
+ {
+ Utils::SmallStringVector ids;
+ ids.reserve(projectParts.size());
+ for (const auto &projectPart : projectParts)
+ ids.emplace_back(projectPart.projectPartId);
+
+ std::sort(ids.begin(), ids.end());
+
+ return ids;
+ }
+
+ void removeEmptyEntries()
+ {
+ auto newEnd = std::remove_if(m_argumentEntries.begin(),
+ m_argumentEntries.end(),
+ [](const auto &entry) { return entry.ids.empty(); });
+
+ m_argumentEntries.erase(newEnd, m_argumentEntries.end());
+ }
+
+private:
+ std::vector<ArgumentsEntry> m_argumentEntries;
+};
+
+}
diff --git a/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h b/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h
index 459eab6282..05e6a8eaf6 100644
--- a/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h
+++ b/src/tools/clangpchmanagerbackend/source/usedmacrofilter.h
@@ -52,6 +52,8 @@ public:
{
systemIncludes.reserve(includes.size());
projectIncludes.reserve(includes.size());
+ topSystemIncludes.reserve(includes.size() / 10);
+ topProjectIncludes.reserve(includes.size() / 10);
for (SourceEntry include : includes)
filterInclude(include);
@@ -76,10 +78,16 @@ private:
{
switch (include.sourceType) {
case SourceType::TopSystemInclude:
+ topSystemIncludes.emplace_back(include.sourceId);
+ systemIncludes.emplace_back(include.sourceId);
+ break;
case SourceType::SystemInclude:
systemIncludes.emplace_back(include.sourceId);
break;
case SourceType::TopProjectInclude:
+ topProjectIncludes.emplace_back(include.sourceId);
+ projectIncludes.emplace_back(include.sourceId);
+ break;
case SourceType::ProjectInclude:
projectIncludes.emplace_back(include.sourceId);
break;
@@ -173,6 +181,8 @@ private:
public:
FilePathIds projectIncludes;
FilePathIds systemIncludes;
+ FilePathIds topProjectIncludes;
+ FilePathIds topSystemIncludes;
UsedMacros projectUsedMacros;
UsedMacros systemUsedMacros;
CompilerMacros projectCompilerMacros;
diff --git a/src/tools/clangrefactoringbackend/source/clangtool.cpp b/src/tools/clangrefactoringbackend/source/clangtool.cpp
index e2df298c8d..dea6e1190a 100644
--- a/src/tools/clangrefactoringbackend/source/clangtool.cpp
+++ b/src/tools/clangrefactoringbackend/source/clangtool.cpp
@@ -50,9 +50,9 @@ void ClangTool::addFile(std::string &&directory,
std::vector<std::string> &&commandLine)
{
m_fileContents.emplace_back(toNativePath(std::move(directory)),
- std::move(fileName),
- std::move(content),
- std::move(commandLine));
+ std::move(fileName),
+ std::move(content),
+ std::move(commandLine));
const auto &fileContent = m_fileContents.back();
@@ -140,4 +140,13 @@ clang::tooling::ClangTool ClangTool::createTool() const
return tool;
}
+clang::tooling::ClangTool ClangTool::createOutputTool() const
+{
+ clang::tooling::ClangTool tool = createTool();
+
+ tool.clearArgumentsAdjusters();
+
+ return tool;
+}
+
} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/clangtool.h b/src/tools/clangrefactoringbackend/source/clangtool.h
index 9f0676a397..deee71599b 100644
--- a/src/tools/clangrefactoringbackend/source/clangtool.h
+++ b/src/tools/clangrefactoringbackend/source/clangtool.h
@@ -91,6 +91,7 @@ public:
void addUnsavedFiles(const V2::FileContainers &unsavedFiles);
clang::tooling::ClangTool createTool() const;
+ clang::tooling::ClangTool createOutputTool() const;
private:
RefactoringCompilationDatabase m_compilationDatabase;
diff --git a/src/tools/clangrefactoringbackend/source/projectpartartefact.cpp b/src/tools/clangrefactoringbackend/source/projectpartartefact.cpp
index 13856e1411..1c62bec8fe 100644
--- a/src/tools/clangrefactoringbackend/source/projectpartartefact.cpp
+++ b/src/tools/clangrefactoringbackend/source/projectpartartefact.cpp
@@ -33,16 +33,7 @@
namespace ClangBackEnd {
-ProjectPartArtefact::ProjectPartArtefact(Utils::SmallStringView compilerArgumentsText,
- Utils::SmallStringView compilerMacrosText,
- Utils::SmallStringView includeSearchPaths,
- int projectPartId)
- : compilerArguments(toStringVector(compilerArgumentsText)),
- compilerMacros(toCompilerMacros(compilerMacrosText)),
- includeSearchPaths(toStringVector(includeSearchPaths)),
- projectPartId(projectPartId)
-{
-}
+
Utils::SmallStringVector ProjectPartArtefact::toStringVector(Utils::SmallStringView jsonText)
{
@@ -58,19 +49,35 @@ Utils::SmallStringVector ProjectPartArtefact::toStringVector(Utils::SmallStringV
CompilerMacros ProjectPartArtefact::createCompilerMacrosFromDocument(const QJsonDocument &document)
{
- QJsonObject object = document.object();
+ QJsonArray array = document.array();
CompilerMacros macros;
- macros.reserve(object.size());
+ macros.reserve(array.size());
- int index = 0;
- for (auto current = object.constBegin(); current != object.constEnd(); ++current)
- macros.emplace_back(current.key(), current.value().toString(), ++index);
+ for (const QJsonValueRef entry : array) {
+ const QJsonArray entryArray = entry.toArray();
+ macros.emplace_back(
+ entryArray[0].toString(), entryArray[1].toString(), entryArray[2].toInt());
+ }
std::sort(macros.begin(), macros.end());
return macros;
}
+IncludeSearchPaths ProjectPartArtefact::createIncludeSearchPathsFromDocument(const QJsonDocument &document)
+{
+ QJsonArray array = document.array();
+ IncludeSearchPaths paths;
+ paths.reserve(array.size());
+
+ for (const QJsonValueRef entry : array) {
+ const QJsonArray entryArray = entry.toArray();
+ paths.emplace_back(entryArray[0].toString(), entryArray[1].toInt(), entryArray[2].toInt());
+ }
+
+ return paths;
+}
+
CompilerMacros ProjectPartArtefact::toCompilerMacros(Utils::SmallStringView jsonText)
{
if (jsonText.isEmpty())
@@ -93,6 +100,17 @@ QJsonDocument ProjectPartArtefact::createJsonDocument(Utils::SmallStringView jso
return document;
}
+IncludeSearchPaths ProjectPartArtefact::toIncludeSearchPaths(Utils::SmallStringView jsonText)
+{
+
+ if (jsonText.isEmpty())
+ return {};
+
+ QJsonDocument document = createJsonDocument(jsonText, "Include search paths parsing error");
+
+ return createIncludeSearchPathsFromDocument(document);
+}
+
void ProjectPartArtefact::checkError(const char *whatError, const QJsonParseError &error)
{
if (error.error != QJsonParseError::NoError) {
@@ -104,7 +122,9 @@ void ProjectPartArtefact::checkError(const char *whatError, const QJsonParseErro
bool operator==(const ProjectPartArtefact &first, const ProjectPartArtefact &second)
{
return first.compilerArguments == second.compilerArguments
- && first.compilerMacros == second.compilerMacros;
+ && first.compilerMacros == second.compilerMacros
+ && first.systemIncludeSearchPaths == second.systemIncludeSearchPaths
+ && first.projectIncludeSearchPaths == second.projectIncludeSearchPaths;
}
} // namespace ClangBackEnd
diff --git a/src/tools/clangrefactoringbackend/source/projectpartartefact.h b/src/tools/clangrefactoringbackend/source/projectpartartefact.h
index ee508abe27..44ca9acadb 100644
--- a/src/tools/clangrefactoringbackend/source/projectpartartefact.h
+++ b/src/tools/clangrefactoringbackend/source/projectpartartefact.h
@@ -30,6 +30,7 @@
#include <utils/smallstringvector.h>
#include <compilermacro.h>
+#include <includesearchpath.h>
QT_FORWARD_DECLARE_CLASS(QJsonDocument)
QT_FORWARD_DECLARE_STRUCT(QJsonParseError)
@@ -41,27 +42,30 @@ class ProjectPartArtefact
public:
ProjectPartArtefact(Utils::SmallStringView compilerArgumentsText,
Utils::SmallStringView compilerMacrosText,
- Utils::SmallStringView includeSearchPaths,
- int projectPartId);
+ Utils::SmallStringView systemIncludeSearchPathsText,
+ Utils::SmallStringView projectIncludeSearchPathsText,
+ int projectPartId)
+ : compilerArguments(toStringVector(compilerArgumentsText))
+ , compilerMacros(toCompilerMacros(compilerMacrosText))
+ , systemIncludeSearchPaths(toIncludeSearchPaths(systemIncludeSearchPathsText))
+ , projectIncludeSearchPaths(toIncludeSearchPaths(projectIncludeSearchPathsText))
+ , projectPartId(projectPartId)
+ {}
- static
- Utils::SmallStringVector toStringVector(Utils::SmallStringView jsonText);
- static
- CompilerMacros createCompilerMacrosFromDocument(const QJsonDocument &document);
- static
- CompilerMacros toCompilerMacros(Utils::SmallStringView jsonText);
- static
- QJsonDocument createJsonDocument(Utils::SmallStringView jsonText,
- const char *whatError);
- static
- void checkError(const char *whatError, const QJsonParseError &error);
- friend
- bool operator==(const ProjectPartArtefact &first, const ProjectPartArtefact &second);
+ static Utils::SmallStringVector toStringVector(Utils::SmallStringView jsonText);
+ static CompilerMacros createCompilerMacrosFromDocument(const QJsonDocument &document);
+ static IncludeSearchPaths createIncludeSearchPathsFromDocument(const QJsonDocument &document);
+ static CompilerMacros toCompilerMacros(Utils::SmallStringView jsonText);
+ static QJsonDocument createJsonDocument(Utils::SmallStringView jsonText, const char *whatError);
+ static IncludeSearchPaths toIncludeSearchPaths(Utils::SmallStringView jsonText);
+ static void checkError(const char *whatError, const QJsonParseError &error);
+ friend bool operator==(const ProjectPartArtefact &first, const ProjectPartArtefact &second);
public:
Utils::SmallStringVector compilerArguments;
CompilerMacros compilerMacros;
- Utils::SmallStringVector includeSearchPaths;
+ IncludeSearchPaths systemIncludeSearchPaths;
+ IncludeSearchPaths projectIncludeSearchPaths;
int projectPartId = -1;
};
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
index 47a02e9fa3..0a45d361d9 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.cpp
@@ -25,8 +25,10 @@
#include "symbolindexer.h"
-#include <symbolscollectorinterface.h>
-#include <symbolindexertaskqueue.h>
+#include "symbolscollectorinterface.h"
+#include "symbolindexertaskqueue.h"
+
+#include <commandlinebuilder.h>
#include <chrono>
#include <iostream>
@@ -65,7 +67,7 @@ SymbolIndexer::SymbolIndexer(SymbolIndexerTaskQueueInterface &symbolIndexerTaskQ
Sqlite::TransactionInterface &transactionInterface)
: m_symbolIndexerTaskQueue(symbolIndexerTaskQueue),
m_symbolStorage(symbolStorage),
- m_usedMacroAndSourceStorage(usedMacroAndSourceStorage),
+ m_buildDependencyStorage(usedMacroAndSourceStorage),
m_pathWatcher(pathWatcher),
m_filePathCache(filePathCache),
m_fileStatusCache(fileStatusCache),
@@ -74,20 +76,22 @@ SymbolIndexer::SymbolIndexer(SymbolIndexerTaskQueueInterface &symbolIndexerTaskQ
pathWatcher.setNotifier(this);
}
-void SymbolIndexer::updateProjectParts(V2::ProjectPartContainers &&projectParts)
+void SymbolIndexer::updateProjectParts(ProjectPartContainers &&projectParts)
{
- for (V2::ProjectPartContainer &projectPart : projectParts)
+ for (ProjectPartContainer &projectPart : projectParts)
updateProjectPart(std::move(projectPart));
}
-void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart)
+void SymbolIndexer::updateProjectPart(ProjectPartContainer &&projectPart)
{
Sqlite::ImmediateTransaction transaction{m_transactionInterface};
const auto optionalArtefact = m_symbolStorage.fetchProjectPartArtefact(projectPart.projectPartId);
- int projectPartId = m_symbolStorage.insertOrUpdateProjectPart(projectPart.projectPartId,
- projectPart.arguments,
- projectPart.compilerMacros,
- projectPart.includeSearchPaths);
+ int projectPartId = m_symbolStorage.insertOrUpdateProjectPart(
+ projectPart.projectPartId,
+ projectPart.toolChainArguments,
+ projectPart.compilerMacros,
+ projectPart.systemIncludeSearchPaths,
+ projectPart.projectIncludeSearchPaths);
if (optionalArtefact)
projectPartId = optionalArtefact->projectPartId;
const Utils::optional<ProjectPartPch> optionalProjectPartPch = m_symbolStorage.fetchPrecompiledHeader(projectPartId);
@@ -97,14 +101,20 @@ void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart)
if (sourcePathIds.empty())
return;
- const Utils::SmallStringVector arguments = compilerArguments(projectPart.arguments,
- optionalProjectPartPch);
+ using Builder = CommandLineBuilder<ProjectPartContainer, Utils::SmallStringVector>;
+ Builder commandLineBuilder{projectPart,
+ projectPart.toolChainArguments,
+ {},
+ {},
+ optionalProjectPartPch
+ ? FilePathView{optionalProjectPartPch.value().pchPath}
+ : FilePathView{}};
std::vector<SymbolIndexerTask> symbolIndexerTask;
symbolIndexerTask.reserve(projectPart.sourcePathIds.size());
for (FilePathId sourcePathId : projectPart.sourcePathIds) {
- auto indexing = [projectPartId, arguments, sourcePathId, this]
- (SymbolsCollectorInterface &symbolsCollector) {
+ auto indexing = [projectPartId, arguments = commandLineBuilder.commandLine, sourcePathId, this](
+ SymbolsCollectorInterface &symbolsCollector) {
symbolsCollector.setFile(sourcePathId, arguments);
symbolsCollector.collectSymbols();
@@ -114,14 +124,14 @@ void SymbolIndexer::updateProjectPart(V2::ProjectPartContainer &&projectPart)
m_symbolStorage.addSymbolsAndSourceLocations(symbolsCollector.symbols(),
symbolsCollector.sourceLocations());
- m_symbolStorage.updateProjectPartSources(projectPartId,
- symbolsCollector.sourceFiles());
+ m_symbolStorage.updateProjectPartSources(projectPartId, symbolsCollector.sourceFiles());
- m_usedMacroAndSourceStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
+ m_buildDependencyStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
- m_usedMacroAndSourceStorage.insertFileStatuses(symbolsCollector.fileStatuses());
+ m_buildDependencyStorage.insertFileStatuses(symbolsCollector.fileStatuses());
- m_usedMacroAndSourceStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
+ m_buildDependencyStorage.insertOrUpdateSourceDependencies(
+ symbolsCollector.sourceDependencies());
transaction.commit();
};
@@ -155,22 +165,23 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
m_fileStatusCache.update(filePathId);
Sqlite::DeferredTransaction transaction{m_transactionInterface};
- const Utils::optional<ProjectPartArtefact> optionalArtefact = m_symbolStorage.fetchProjectPartArtefact(filePathId);
+ const Utils::optional<ProjectPartArtefact> optionalArtefact = m_symbolStorage.fetchProjectPartArtefact(
+ filePathId);
if (!optionalArtefact)
return;
- const Utils::optional<ProjectPartPch> optionalProjectPartPch = m_symbolStorage.fetchPrecompiledHeader(optionalArtefact->projectPartId);
+ const Utils::optional<ProjectPartPch> optionalProjectPartPch = m_symbolStorage.fetchPrecompiledHeader(
+ optionalArtefact->projectPartId);
transaction.commit();
if (!optionalArtefact.value().compilerArguments.empty()) {
-
const ProjectPartArtefact &artefact = optionalArtefact.value();
const Utils::SmallStringVector arguments = compilerArguments(artefact.compilerArguments,
optionalProjectPartPch);
- auto indexing = [projectPartId=artefact.projectPartId, arguments, filePathId, this]
- (SymbolsCollectorInterface &symbolsCollector) {
+ auto indexing = [projectPartId = artefact.projectPartId, arguments, filePathId, this](
+ SymbolsCollectorInterface &symbolsCollector) {
symbolsCollector.setFile(filePathId, arguments);
symbolsCollector.collectSymbols();
@@ -182,39 +193,43 @@ void SymbolIndexer::updateChangedPath(FilePathId filePathId,
m_symbolStorage.updateProjectPartSources(projectPartId, symbolsCollector.sourceFiles());
- m_usedMacroAndSourceStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
+ m_buildDependencyStorage.insertOrUpdateUsedMacros(symbolsCollector.usedMacros());
- m_usedMacroAndSourceStorage.insertFileStatuses(symbolsCollector.fileStatuses());
+ m_buildDependencyStorage.insertFileStatuses(symbolsCollector.fileStatuses());
- m_usedMacroAndSourceStorage.insertOrUpdateSourceDependencies(symbolsCollector.sourceDependencies());
+ m_buildDependencyStorage.insertOrUpdateSourceDependencies(
+ symbolsCollector.sourceDependencies());
transaction.commit();
};
- symbolIndexerTask.emplace_back(filePathId, optionalArtefact->projectPartId, std::move(indexing));
+ symbolIndexerTask.emplace_back(filePathId,
+ optionalArtefact->projectPartId,
+ std::move(indexing));
}
}
bool SymbolIndexer::compilerMacrosOrIncludeSearchPathsAreDifferent(
- const V2::ProjectPartContainer &projectPart,
+ const ProjectPartContainer &projectPart,
const Utils::optional<ProjectPartArtefact> &optionalArtefact) const
{
if (optionalArtefact) {
const ProjectPartArtefact &artefact = optionalArtefact.value();
return projectPart.compilerMacros != artefact.compilerMacros
- || projectPart.includeSearchPaths != artefact.includeSearchPaths;
+ || projectPart.systemIncludeSearchPaths != artefact.systemIncludeSearchPaths
+ || projectPart.projectIncludeSearchPaths != artefact.projectIncludeSearchPaths;
}
return true;
}
-FilePathIds SymbolIndexer::filterChangedFiles(const V2::ProjectPartContainer &projectPart) const
+FilePathIds SymbolIndexer::filterChangedFiles(const ProjectPartContainer &projectPart) const
{
FilePathIds ids;
ids.reserve(projectPart.sourcePathIds.size());
for (const FilePathId &sourceId : projectPart.sourcePathIds) {
- long long oldLastModified = m_usedMacroAndSourceStorage.fetchLowestLastModifiedTime(sourceId);
+ long long oldLastModified = m_buildDependencyStorage.fetchLowestLastModifiedTime(sourceId);
long long currentLastModified = m_fileStatusCache.lastModifiedTime(sourceId);
if (oldLastModified < currentLastModified)
ids.push_back(sourceId);
@@ -223,7 +238,7 @@ FilePathIds SymbolIndexer::filterChangedFiles(const V2::ProjectPartContainer &pr
return ids;
}
-FilePathIds SymbolIndexer::updatableFilePathIds(const V2::ProjectPartContainer &projectPart,
+FilePathIds SymbolIndexer::updatableFilePathIds(const ProjectPartContainer &projectPart,
const Utils::optional<ProjectPartArtefact> &optionalArtefact) const
{
if (compilerMacrosOrIncludeSearchPathsAreDifferent(projectPart, optionalArtefact))
@@ -233,8 +248,8 @@ FilePathIds SymbolIndexer::updatableFilePathIds(const V2::ProjectPartContainer &
}
Utils::SmallStringVector SymbolIndexer::compilerArguments(
- Utils::SmallStringVector arguments,
- const Utils::optional<ProjectPartPch> optionalProjectPartPch) const
+ Utils::SmallStringVector arguments,
+ const Utils::optional<ProjectPartPch> optionalProjectPartPch) const
{
if (optionalProjectPartPch) {
arguments.emplace_back("-Xclang");
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexer.h b/src/tools/clangrefactoringbackend/source/symbolindexer.h
index d9070005ce..55f62ffa5f 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexer.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexer.h
@@ -31,7 +31,7 @@
#include "builddependenciesstorageinterface.h"
#include "clangpathwatcher.h"
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
#include <filecontainerv2.h>
namespace ClangBackEnd {
@@ -49,8 +49,8 @@ public:
FileStatusCache &fileStatusCache,
Sqlite::TransactionInterface &transactionInterface);
- void updateProjectParts(V2::ProjectPartContainers &&projectParts);
- void updateProjectPart(V2::ProjectPartContainer &&projectPart);
+ void updateProjectParts(ProjectPartContainers &&projectParts);
+ void updateProjectPart(ProjectPartContainer &&projectPart);
void pathsWithIdsChanged(const Utils::SmallStringVector &ids) override;
void pathsChanged(const FilePathIds &filePathIds) override;
@@ -58,22 +58,23 @@ public:
std::vector<SymbolIndexerTask> &symbolIndexerTask);
bool compilerMacrosOrIncludeSearchPathsAreDifferent(
- const V2::ProjectPartContainer &projectPart,
+ const ProjectPartContainer &projectPart,
const Utils::optional<ProjectPartArtefact> &optionalArtefact) const;
FilePathIds filterChangedFiles(
- const V2::ProjectPartContainer &projectPart) const;
+ const ProjectPartContainer &projectPart) const;
- FilePathIds updatableFilePathIds(const V2::ProjectPartContainer &projectPart,
+ FilePathIds updatableFilePathIds(const ProjectPartContainer &projectPart,
const Utils::optional<ProjectPartArtefact> &optionalArtefact) const;
- Utils::SmallStringVector compilerArguments(Utils::SmallStringVector arguments,
- const Utils::optional<ProjectPartPch> optionalProjectPartPch) const;
+ Utils::SmallStringVector compilerArguments(
+ Utils::SmallStringVector arguments,
+ const Utils::optional<ProjectPartPch> optionalProjectPartPch) const;
private:
SymbolIndexerTaskQueueInterface &m_symbolIndexerTaskQueue;
SymbolStorageInterface &m_symbolStorage;
- BuildDependenciesStorageInterface &m_usedMacroAndSourceStorage;
+ BuildDependenciesStorageInterface &m_buildDependencyStorage;
ClangPathWatcherInterface &m_pathWatcher;
FilePathCachingInterface &m_filePathCache;
FileStatusCache &m_fileStatusCache;
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.cpp b/src/tools/clangrefactoringbackend/source/symbolindexing.cpp
index 4f62b859f0..529396e9fa 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexing.cpp
+++ b/src/tools/clangrefactoringbackend/source/symbolindexing.cpp
@@ -27,7 +27,7 @@
namespace ClangBackEnd {
-void SymbolIndexing::updateProjectParts(V2::ProjectPartContainers &&projectParts)
+void SymbolIndexing::updateProjectParts(ProjectPartContainers &&projectParts)
{
m_indexer.updateProjectParts(std::move(projectParts));
}
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexing.h b/src/tools/clangrefactoringbackend/source/symbolindexing.h
index 10e1be0358..6f52f863d8 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexing.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexing.h
@@ -81,12 +81,16 @@ public:
FilePathCachingInterface &filePathCache,
const GeneratedFiles &generatedFiles,
ProgressCounter::SetProgressCallback &&setProgressCallback)
- : m_filePathCache(filePathCache),
- m_usedMacroAndSourceStorage(database),
- m_symbolStorage(database),
- m_collectorManger(generatedFiles, database),
- m_progressCounter(std::move(setProgressCallback)),
- m_indexerScheduler(m_collectorManger, m_indexerQueue, m_progressCounter, std::thread::hardware_concurrency())
+ : m_filePathCache(filePathCache)
+ , m_buildDependencyStorage(database)
+ , m_symbolStorage(database)
+ , m_collectorManger(generatedFiles, database)
+ , m_progressCounter(std::move(setProgressCallback))
+ , m_indexerScheduler(m_collectorManger,
+ m_indexerQueue,
+ m_progressCounter,
+ std::thread::hardware_concurrency(),
+ CallDoInMainThreadAfterFinished::Yes)
{
}
@@ -109,12 +113,12 @@ public:
}
}
- void updateProjectParts(V2::ProjectPartContainers &&projectParts) override;
+ void updateProjectParts(ProjectPartContainers &&projectParts) override;
private:
using SymbolIndexerTaskScheduler = TaskScheduler<SymbolsCollectorManager, SymbolIndexerTask::Callable>;
FilePathCachingInterface &m_filePathCache;
- BuildDependenciesStorage m_usedMacroAndSourceStorage;
+ BuildDependenciesStorage m_buildDependencyStorage;
SymbolStorage m_symbolStorage;
ClangPathWatcher<QFileSystemWatcher, QTimer> m_sourceWatcher{m_filePathCache};
FileStatusCache m_fileStatusCache{m_filePathCache};
@@ -124,7 +128,7 @@ private:
SymbolIndexerTaskQueue m_indexerQueue{m_indexerScheduler, m_progressCounter};
SymbolIndexer m_indexer{m_indexerQueue,
m_symbolStorage,
- m_usedMacroAndSourceStorage,
+ m_buildDependencyStorage,
m_sourceWatcher,
m_filePathCache,
m_fileStatusCache,
diff --git a/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h b/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h
index 70e16d7429..3feb9e1b9f 100644
--- a/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h
+++ b/src/tools/clangrefactoringbackend/source/symbolindexinginterface.h
@@ -25,7 +25,7 @@
#pragma once
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
#include <filecontainerv2.h>
namespace ClangBackEnd {
@@ -37,7 +37,7 @@ public:
SymbolIndexingInterface(const SymbolIndexingInterface&) = delete;
SymbolIndexingInterface &operator=(const SymbolIndexingInterface&) = delete;
- virtual void updateProjectParts(V2::ProjectPartContainers &&projectParts) = 0;
+ virtual void updateProjectParts(ProjectPartContainers &&projectParts) = 0;
protected:
~SymbolIndexingInterface() = default;
diff --git a/src/tools/clangrefactoringbackend/source/symbolstorage.h b/src/tools/clangrefactoringbackend/source/symbolstorage.h
index 02d52bfb50..0be04c04b6 100644
--- a/src/tools/clangrefactoringbackend/source/symbolstorage.h
+++ b/src/tools/clangrefactoringbackend/source/symbolstorage.h
@@ -31,6 +31,7 @@
#include <sqliteexception.h>
#include <sqlitetransaction.h>
#include <sqlitetable.h>
+#include <includesearchpath.h>
#include <QJsonArray>
#include <QJsonDocument>
@@ -68,45 +69,39 @@ public:
}
int insertOrUpdateProjectPart(Utils::SmallStringView projectPartName,
- const Utils::SmallStringVector &commandLineArguments,
- const CompilerMacros &compilerMacros,
- const Utils::SmallStringVector &includeSearchPaths) override
+ const Utils::SmallStringVector &commandLineArguments,
+ const CompilerMacros &compilerMacros,
+ const IncludeSearchPaths &systemIncludeSearchPaths,
+ const IncludeSearchPaths &projectIncludeSearchPaths) override
{
- m_database.setLastInsertedRowId(-1);
-
Utils::SmallString compilerArguementsAsJson = toJson(commandLineArguments);
Utils::SmallString compilerMacrosAsJson = toJson(compilerMacros);
- Utils::SmallString includeSearchPathsAsJason = toJson(includeSearchPaths);
-
- WriteStatement &insertStatement = m_insertProjectPartStatement;
- insertStatement.write(projectPartName,
- compilerArguementsAsJson,
- compilerMacrosAsJson,
- includeSearchPathsAsJason);
-
- if (m_database.lastInsertedRowId() == -1) {
- WriteStatement &updateStatement = m_updateProjectPartStatement;
- updateStatement.write(compilerArguementsAsJson,
- compilerMacrosAsJson,
- includeSearchPathsAsJason,
- projectPartName);
- }
+ Utils::SmallString systemIncludeSearchPathsAsJason = toJson(systemIncludeSearchPaths);
+ Utils::SmallString projectIncludeSearchPathsAsJason = toJson(projectIncludeSearchPaths);
+
+ m_insertOrUpdateProjectPartStatement.write(projectPartName,
+ compilerArguementsAsJson,
+ compilerMacrosAsJson,
+ systemIncludeSearchPathsAsJason,
+ projectIncludeSearchPathsAsJason);
+
+ auto projectPartId = m_getProjectPartIdStatement.template value<int>(projectPartName);
- return int(m_database.lastInsertedRowId());
+ return projectPartId.value();
}
Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(FilePathId sourceId) const override
{
ReadStatement &statement = m_getProjectPartArtefactsBySourceId;
- return statement.template value<ProjectPartArtefact, 4>(sourceId.filePathId);
+ return statement.template value<ProjectPartArtefact, 5>(sourceId.filePathId);
}
Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(Utils::SmallStringView projectPartName) const override
{
ReadStatement &statement = m_getProjectPartArtefactsByProjectPartName;
- return statement.template value<ProjectPartArtefact, 4>(projectPartName);
+ return statement.template value<ProjectPartArtefact, 5>(projectPartName);
}
void updateProjectPartSources(int projectPartId,
@@ -137,12 +132,25 @@ public:
static Utils::SmallString toJson(const CompilerMacros &compilerMacros)
{
QJsonDocument document;
- QJsonObject object;
+ QJsonArray array;
for (const CompilerMacro &macro : compilerMacros)
- object.insert(QString(macro.key), QString(macro.value));
+ array.push_back(QJsonArray{{QString(macro.key), QString(macro.value), macro.index}});
- document.setObject(object);
+ document.setArray(array);
+
+ return document.toJson(QJsonDocument::Compact);
+ }
+
+ static Utils::SmallString toJson(const IncludeSearchPaths &includeSearchPaths)
+ {
+ QJsonDocument document;
+ QJsonArray array;
+
+ for (const IncludeSearchPath &path : includeSearchPaths)
+ array.push_back(QJsonArray{{path.path.data(), path.index, int(path.type)}});
+
+ document.setArray(array);
return document.toJson(QJsonDocument::Compact);
}
@@ -299,14 +307,12 @@ public:
"DELETE FROM newLocations",
m_database
};
- WriteStatement m_insertProjectPartStatement{
- "INSERT OR IGNORE INTO projectParts(projectPartName, compilerArguments, compilerMacros, includeSearchPaths) VALUES (?,?,?,?)",
- m_database
- };
- WriteStatement m_updateProjectPartStatement{
- "UPDATE projectParts SET compilerArguments = ?, compilerMacros = ?, includeSearchPaths = ? WHERE projectPartName = ?",
- m_database
- };
+ WriteStatement m_insertOrUpdateProjectPartStatement{
+ "INSERT INTO projectParts(projectPartName, compilerArguments, compilerMacros, "
+ "systemIncludeSearchPaths, projectIncludeSearchPaths) VALUES (?001,?002,?003,?004,?005) ON "
+ "CONFLICT(projectPartName) DO UPDATE SET compilerArguments=?002, compilerMacros=?003, "
+ "systemIncludeSearchPaths=?004, projectIncludeSearchPaths=?005",
+ m_database};
mutable ReadStatement m_getProjectPartIdStatement{
"SELECT projectPartId FROM projectParts WHERE projectPartName = ?",
m_database
@@ -324,13 +330,14 @@ public:
m_database
};
mutable ReadStatement m_getProjectPartArtefactsBySourceId{
- "SELECT compilerArguments, compilerMacros, includeSearchPaths, projectPartId FROM projectParts WHERE projectPartId = (SELECT projectPartId FROM projectPartsSources WHERE sourceId = ?)",
- m_database
- };
+ "SELECT compilerArguments, compilerMacros, systemIncludeSearchPaths, projectIncludeSearchPaths, "
+ "projectPartId FROM projectParts WHERE projectPartId = (SELECT projectPartId FROM "
+ "projectPartsSources WHERE sourceId = ?)",
+ m_database};
mutable ReadStatement m_getProjectPartArtefactsByProjectPartName{
- "SELECT compilerArguments, compilerMacros, includeSearchPaths, projectPartId FROM projectParts WHERE projectPartName = ?",
- m_database
- };
+ "SELECT compilerArguments, compilerMacros, systemIncludeSearchPaths, "
+ "projectIncludeSearchPaths, projectPartId FROM projectParts WHERE projectPartName = ?",
+ m_database};
mutable ReadStatement m_getPrecompiledHeader{
"SELECT projectPchPath, projectPchBuildTime FROM precompiledHeaders WHERE projectPartId = ?",
m_database
diff --git a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h
index 0cb1dafd4f..3e51302c20 100644
--- a/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h
+++ b/src/tools/clangrefactoringbackend/source/symbolstorageinterface.h
@@ -34,6 +34,8 @@
#include "symbolentry.h"
#include "usedmacro.h"
+#include <includesearchpath.h>
+
#include <sqlitetransaction.h>
#include <compilermacro.h>
@@ -48,15 +50,20 @@ public:
SymbolStorageInterface &operator=(const SymbolStorageInterface &) = delete;
virtual void addSymbolsAndSourceLocations(const SymbolEntries &symbolEntries,
- const SourceLocationEntries &sourceLocations) = 0;
- virtual int insertOrUpdateProjectPart(Utils::SmallStringView projectPartName,
- const Utils::SmallStringVector &commandLineArguments,
- const CompilerMacros &compilerMacros,
- const Utils::SmallStringVector &includeSearchPaths) = 0;
- virtual void updateProjectPartSources(int projectPartId,
- const FilePathIds &sourceFilePathIds) = 0;
- virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(FilePathId sourceId) const = 0;
- virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(Utils::SmallStringView projectPartName) const = 0;
+ const SourceLocationEntries &sourceLocations)
+ = 0;
+ virtual int insertOrUpdateProjectPart(
+ Utils::SmallStringView projectPartName,
+ const Utils::SmallStringVector &commandLineArguments,
+ const CompilerMacros &compilerMacros,
+ const ClangBackEnd::IncludeSearchPaths &systemIncludeSearchPaths,
+ const ClangBackEnd::IncludeSearchPaths &projectIncludeSearchPaths)
+ = 0;
+ virtual void updateProjectPartSources(int projectPartId, const FilePathIds &sourceFilePathIds) = 0;
+ virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(
+ FilePathId sourceId) const = 0;
+ virtual Utils::optional<ProjectPartArtefact> fetchProjectPartArtefact(
+ Utils::SmallStringView projectPartName) const = 0;
virtual Utils::optional<ProjectPartPch> fetchPrecompiledHeader(int projectPartId) const = 0;
protected:
diff --git a/tests/unit/unittest/builddependenciesprovider-test.cpp b/tests/unit/unittest/builddependenciesprovider-test.cpp
index cb39ec2bdf..2a5372c55d 100644
--- a/tests/unit/unittest/builddependenciesprovider-test.cpp
+++ b/tests/unit/unittest/builddependenciesprovider-test.cpp
@@ -63,18 +63,28 @@ protected:
mockModifiedTimeChecker,
mockBuildDependenciesGenerator,
mockSqliteTransactionBackend};
- ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1",
- {"--yi"},
- {{"YI", "1", 1}},
- {"/yi"},
- {1},
- {2}};
- ClangBackEnd::V2::ProjectPartContainer projectPart2{"ProjectPart2",
- {"--er"},
- {{"ER", "2", 1}},
- {"/er"},
- {1},
- {2, 3, 4}};
+ ClangBackEnd::ProjectPartContainer projectPart1{
+ "ProjectPart1",
+ {"--yi"},
+ {{"YI", "1", 1}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
+ {{"/project/yi", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {1},
+ {2},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All};
+ ClangBackEnd::ProjectPartContainer projectPart2{
+ "ProjectPart2",
+ {"--er"},
+ {{"ER", "2", 1}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
+ {{"/project/er", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {1},
+ {2, 3, 4},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All};
SourceEntries firstSources{{1, SourceType::UserInclude, 1},
{2, SourceType::UserInclude, 1},
{10, SourceType::UserInclude, 1}};
diff --git a/tests/unit/unittest/builddependencycollector-test.cpp b/tests/unit/unittest/builddependencycollector-test.cpp
index 7a65361edb..1b42f143a0 100644
--- a/tests/unit/unittest/builddependencycollector-test.cpp
+++ b/tests/unit/unittest/builddependencycollector-test.cpp
@@ -529,25 +529,27 @@ TEST_F(BuildDependencyCollector, MissingInclude)
TEST_F(BuildDependencyCollector, Create)
{
+ using ClangBackEnd::IncludeSearchPathType;
ClangBackEnd::BuildDependencyCollector collector{filePathCache};
- ClangBackEnd::V2::ProjectPartContainer
- projectPart{"project1",
- {"cc",
- "-I",
- TESTDATA_DIR "/builddependencycollector/external",
- "-I",
- TESTDATA_DIR "/builddependencycollector/project",
- "-isystem",
- TESTDATA_DIR "/builddependencycollector/system"},
- {},
- {},
- {
- id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
- id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
- id(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"),
- id(TESTDATA_DIR "/builddependencycollector/project/macros.h"),
- },
- {id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp")}};
+ ClangBackEnd::ProjectPartContainer projectPart{
+ "project1",
+ {},
+ {},
+ {{TESTDATA_DIR "/builddependencycollector/system", 1, IncludeSearchPathType::System}},
+ {
+ {TESTDATA_DIR "/builddependencycollector/project", 1, IncludeSearchPathType::User},
+ {TESTDATA_DIR "/builddependencycollector/external", 2, IncludeSearchPathType::User},
+ },
+ {
+ id(TESTDATA_DIR "/builddependencycollector/project/header1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
+ id(TESTDATA_DIR "/builddependencycollector/project/missingfile.h"),
+ id(TESTDATA_DIR "/builddependencycollector/project/macros.h"),
+ },
+ {id(TESTDATA_DIR "/builddependencycollector/project/main4.cpp")},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::CXX11,
+ Utils::LanguageExtension::None};
auto buildDependency = collector.create(projectPart);
diff --git a/tests/unit/unittest/commandlinebuilder-test.cpp b/tests/unit/unittest/commandlinebuilder-test.cpp
new file mode 100644
index 0000000000..6cf673bf83
--- /dev/null
+++ b/tests/unit/unittest/commandlinebuilder-test.cpp
@@ -0,0 +1,481 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <commandlinebuilder.h>
+#include <pchtask.h>
+#include <projectpartcontainer.h>
+
+namespace {
+template<typename ProjectInfo>
+using Builder = ClangBackEnd::CommandLineBuilder<ProjectInfo>;
+
+using ClangBackEnd::IncludeSearchPathType;
+
+template <typename ProjectInfo>
+class CommandLineBuilder : public testing::Test
+{
+};
+
+template <>
+class CommandLineBuilder<ClangBackEnd::PchTask> : public testing::Test
+{
+public:
+ CommandLineBuilder()
+ {
+ cppProjectInfo.language = Utils::Language::Cxx;
+ }
+
+public:
+ ClangBackEnd::PchTask emptyProjectInfo{"empty", {}, {}, {}, {}, {}, {}};
+ ClangBackEnd::PchTask cppProjectInfo{"project1", {}, {}, {}, {}, {}, {}};
+};
+
+template <>
+class CommandLineBuilder<ClangBackEnd::ProjectPartContainer> : public testing::Test
+{
+public:
+ CommandLineBuilder()
+ {
+ cppProjectInfo.language = Utils::Language::Cxx;
+ }
+
+public:
+ ClangBackEnd::ProjectPartContainer emptyProjectInfo{"empty",
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::CXX98,
+ Utils::LanguageExtension::None};
+ ClangBackEnd::ProjectPartContainer cppProjectInfo{"project1",
+ {},
+ {},
+ {},
+ {},
+ {},
+ {},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::CXX98,
+ Utils::LanguageExtension::None};
+};
+
+using ProjectInfos = testing::Types<ClangBackEnd::PchTask, ClangBackEnd::ProjectPartContainer>;
+TYPED_TEST_SUITE(CommandLineBuilder, ProjectInfos);
+
+TYPED_TEST(CommandLineBuilder, AddToolChainArguments)
+{
+ Builder<TypeParam> builder{this->emptyProjectInfo, {"-m64", "-PIC"}, {}};
+
+ ASSERT_THAT(builder.commandLine, AllOf(Contains("-m64"), Contains("-PIC")));
+}
+
+TYPED_TEST(CommandLineBuilder, CTask)
+{
+ this->emptyProjectInfo.language = Utils::Language::C;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C11;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
+
+ ASSERT_THAT(
+ builder.commandLine,
+ ElementsAre("clang", "-x", "c-header", "-std=c11", "-nostdinc", "-nostdlibinc", "/source/file.c"));
+}
+
+TYPED_TEST(CommandLineBuilder, ObjectiveCTask)
+{
+ this->emptyProjectInfo.language = Utils::Language::C;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::ObjectiveC;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C11;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
+
+ ASSERT_THAT(builder.commandLine,
+ ElementsAre("clang",
+ "-x",
+ "objective-c-header",
+ "-std=c11",
+ "-nostdinc",
+ "-nostdlibinc",
+ "/source/file.c"));
+}
+
+TYPED_TEST(CommandLineBuilder, CppTask)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX98;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine,
+ ElementsAre("clang++",
+ "-x",
+ "c++-header",
+ "-std=c++98",
+ "-nostdinc",
+ "-nostdlibinc",
+ "/source/file.cpp"));
+}
+
+TYPED_TEST(CommandLineBuilder, ObjectiveCppTask)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::ObjectiveC;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX98;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine,
+ ElementsAre("clang++",
+ "-x",
+ "objective-c++-header",
+ "-std=c++98",
+ "-nostdinc",
+ "-nostdlibinc",
+ "/source/file.cpp"));
+}
+
+TYPED_TEST(CommandLineBuilder, Cpp98)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX98;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=c++98"));
+}
+
+TYPED_TEST(CommandLineBuilder, Cpp03)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX03;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=c++03"));
+}
+
+TYPED_TEST(CommandLineBuilder, Cpp11)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX11;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=c++11"));
+}
+
+TYPED_TEST(CommandLineBuilder, Cpp14)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX14;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=c++14"));
+}
+
+TYPED_TEST(CommandLineBuilder, Cpp17)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX17;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=c++17"));
+}
+
+TYPED_TEST(CommandLineBuilder, Cpp20)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX2a;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=c++2a"));
+}
+
+TYPED_TEST(CommandLineBuilder, GnuCpp98)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX98;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=gnu++98"));
+}
+
+TYPED_TEST(CommandLineBuilder, GnuCpp03)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX03;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=gnu++03"));
+}
+
+TYPED_TEST(CommandLineBuilder, GnuCpp11)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX11;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=gnu++11"));
+}
+
+TYPED_TEST(CommandLineBuilder, GnuCpp14)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX14;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=gnu++14"));
+}
+
+TYPED_TEST(CommandLineBuilder, GnuCpp17)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX17;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=gnu++17"));
+}
+
+TYPED_TEST(CommandLineBuilder, GnuCpp20)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX2a;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=gnu++2a"));
+}
+
+TYPED_TEST(CommandLineBuilder, C89)
+{
+ this->emptyProjectInfo.language = Utils::Language::C;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C89;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=c89"));
+}
+
+TYPED_TEST(CommandLineBuilder, C99)
+{
+ this->emptyProjectInfo.language = Utils::Language::C;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C99;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=c99"));
+}
+
+TYPED_TEST(CommandLineBuilder, C11)
+{
+ this->emptyProjectInfo.language = Utils::Language::C;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C11;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=c11"));
+}
+
+TYPED_TEST(CommandLineBuilder, C18)
+{
+ this->emptyProjectInfo.language = Utils::Language::C;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C18;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=c18"));
+}
+
+TYPED_TEST(CommandLineBuilder, GnuC89)
+{
+ this->emptyProjectInfo.language = Utils::Language::C;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C89;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=gnu89"));
+}
+
+TYPED_TEST(CommandLineBuilder, GnuC99)
+{
+ this->emptyProjectInfo.language = Utils::Language::C;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C99;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=gnu99"));
+}
+
+TYPED_TEST(CommandLineBuilder, GnuC11)
+{
+ this->emptyProjectInfo.language = Utils::Language::C;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C11;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=gnu11"));
+}
+
+TYPED_TEST(CommandLineBuilder, GnuC18)
+{
+ this->emptyProjectInfo.language = Utils::Language::C;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::C18;
+ this->emptyProjectInfo.languageExtension = Utils::LanguageExtension::Gnu;
+
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.c"};
+
+ ASSERT_THAT(builder.commandLine, Contains("-std=gnu18"));
+}
+
+TYPED_TEST(CommandLineBuilder, IncludesOrder)
+{
+ this->emptyProjectInfo.language = Utils::Language::Cxx;
+ this->emptyProjectInfo.languageVersion = Utils::LanguageVersion::CXX11;
+ this->emptyProjectInfo.projectIncludeSearchPaths = {{"/include/bar", 2, IncludeSearchPathType::User},
+ {"/include/foo", 1, IncludeSearchPathType::User}};
+ this->emptyProjectInfo.systemIncludeSearchPaths = {{"/system/bar", 4, IncludeSearchPathType::System},
+ {"/system/foo", 3, IncludeSearchPathType::Framework},
+ {"/builtin/bar", 2, IncludeSearchPathType::BuiltIn},
+ {"/builtin/foo", 1, IncludeSearchPathType::BuiltIn}};
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine,
+ ElementsAre("clang++",
+ "-x",
+ "c++-header",
+ "-std=c++11",
+ "-nostdinc",
+ "-nostdlibinc",
+ "-I",
+ "/include/foo",
+ "-I",
+ "/include/bar",
+ "-F",
+ "/system/foo",
+ "-isystem",
+ "/system/bar",
+ "-isystem",
+ "/builtin/foo",
+ "-isystem",
+ "/builtin/bar",
+ "/source/file.cpp"));
+}
+
+TYPED_TEST(CommandLineBuilder, EmptySourceFile)
+{
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, {}};
+
+ ASSERT_THAT(builder.commandLine,
+ ElementsAre("clang++", "-x", "c++-header", "-std=c++98", "-nostdinc", "-nostdlibinc"));
+}
+
+TYPED_TEST(CommandLineBuilder, SourceFile)
+{
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp"};
+
+ ASSERT_THAT(builder.commandLine,
+ ElementsAre("clang++",
+ "-x",
+ "c++-header",
+ "-std=c++98",
+ "-nostdinc",
+ "-nostdlibinc",
+ "/source/file.cpp"));
+}
+
+
+TYPED_TEST(CommandLineBuilder, EmptyOutputFile)
+{
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp", ""};
+
+ ASSERT_THAT(builder.commandLine,
+ ElementsAre("clang++",
+ "-x",
+ "c++-header",
+ "-std=c++98",
+ "-nostdinc",
+ "-nostdlibinc",
+ "/source/file.cpp"));
+}
+
+TYPED_TEST(CommandLineBuilder, OutputFile)
+{
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp", "/output/file.o"};
+
+ ASSERT_THAT(builder.commandLine,
+ ElementsAre("clang++",
+ "-x",
+ "c++-header",
+ "-std=c++98",
+ "-nostdinc",
+ "-nostdlibinc",
+ "-o",
+ "/output/file.o",
+ "/source/file.cpp"));
+}
+
+TYPED_TEST(CommandLineBuilder, IncludePchPath)
+{
+ Builder<TypeParam> builder{this->emptyProjectInfo, {}, "/source/file.cpp", "/output/file.o", "/pch/file.pch"};
+
+ ASSERT_THAT(builder.commandLine,
+ ElementsAre("clang++",
+ "-x",
+ "c++-header",
+ "-std=c++98",
+ "-nostdinc",
+ "-nostdlibinc",
+ "-Xclang",
+ "-include-pch",
+ "-Xclang",
+ "/pch/file.pch",
+ "-o",
+ "/output/file.o",
+ "/source/file.cpp"));
+}
+
+} // namespace
diff --git a/tests/unit/unittest/google-using-declarations.h b/tests/unit/unittest/google-using-declarations.h
index fbf4e249f4..e8bbd52800 100644
--- a/tests/unit/unittest/google-using-declarations.h
+++ b/tests/unit/unittest/google-using-declarations.h
@@ -38,6 +38,7 @@ using testing::Assign;
using testing::ByMove;
using testing::ByRef;
using testing::Contains;
+using testing::ContainerEq;
using testing::ElementsAre;
using testing::Field;
using testing::HasSubstr;
diff --git a/tests/unit/unittest/googletest.h b/tests/unit/unittest/googletest.h
index e5d221d6a8..b685b83c78 100644
--- a/tests/unit/unittest/googletest.h
+++ b/tests/unit/unittest/googletest.h
@@ -33,6 +33,7 @@
#include <gmock/gmock-matchers.h>
#include <gtest/gtest.h>
#include <gtest/gtest-printers.h>
+#include <gtest/gtest-typed-test.h>
#include "compare-operators.h"
diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp
index 36e9cdf891..8b2fbcd226 100644
--- a/tests/unit/unittest/gtest-creator-printing.cpp
+++ b/tests/unit/unittest/gtest-creator-printing.cpp
@@ -42,6 +42,7 @@
#include <filestatus.h>
#include <filepath.h>
#include <fulltokeninfo.h>
+#include <includesearchpath.h>
#include <nativefilepath.h>
#include <pchcreator.h>
#include <pchtask.h>
@@ -56,6 +57,7 @@
#include <symbolindexertaskqueue.h>
#include <symbol.h>
#include <tooltipinfo.h>
+#include <toolchainargumentscache.h>
#include <projectpartentry.h>
#include <usedmacro.h>
@@ -181,6 +183,100 @@ std::ostream &operator<<(std::ostream &out, const LineColumn &lineColumn)
return out << "(" << lineColumn.line << ", " << lineColumn.column << ")";
}
+const char * toText(Utils::Language language)
+{
+ using Utils::Language;
+
+ switch (language) {
+ case Language::C:
+ return "C";
+ case Language::Cxx:
+ return "Cxx";
+ }
+
+ return "";
+}
+
+std::ostream &operator<<(std::ostream &out, const Utils::Language &language)
+{
+ return out << "Utils::" << toText(language);
+}
+
+const char * toText(Utils::LanguageVersion languageVersion)
+{
+ using Utils::LanguageVersion;
+
+ switch (languageVersion) {
+ case LanguageVersion::C11:
+ return "C11";
+ case LanguageVersion::C18:
+ return "C18";
+ case LanguageVersion::C89:
+ return "C89";
+ case LanguageVersion::C99:
+ return "C99";
+ case LanguageVersion::CXX03:
+ return "CXX03";
+ case LanguageVersion::CXX11:
+ return "CXX11";
+ case LanguageVersion::CXX14:
+ return "CXX14";
+ case LanguageVersion::CXX17:
+ return "CXX17";
+ case LanguageVersion::CXX2a:
+ return "CXX2a";
+ case LanguageVersion::CXX98:
+ return "CXX98";
+ }
+
+ return "";
+}
+
+std::ostream &operator<<(std::ostream &out, const Utils::LanguageVersion &languageVersion)
+{
+ return out << "Utils::" << toText(languageVersion);
+}
+
+const std::string toText(Utils::LanguageExtension extension, std::string prefix = {})
+{
+ std::stringstream out;
+ using Utils::LanguageExtension;
+
+ if (extension == LanguageExtension::None) {
+ out << prefix << "None";
+ } else if (extension == LanguageExtension::All) {
+ out << prefix << "All";
+ } else {
+ std::string split = "";
+ if (extension == LanguageExtension::Gnu) {
+ out << prefix << "Gnu";
+ split = " | ";
+ }
+ if (extension == LanguageExtension::Microsoft) {
+ out << split << prefix << "Microsoft";
+ split = " | ";
+ }
+ if (extension == LanguageExtension::Borland) {
+ out << split << prefix << "Borland";
+ split = " | ";
+ }
+ if (extension == LanguageExtension::OpenMP) {
+ out << split << prefix << "OpenMP";
+ split = " | ";
+ }
+ if (extension == LanguageExtension::ObjectiveC) {
+ out << split << prefix << "ObjectiveC";
+ }
+ }
+
+ return out.str();
+}
+
+std::ostream &operator<<(std::ostream &out, const Utils::LanguageExtension &languageExtension)
+{
+ return out << toText(languageExtension, "Utils::");
+}
+
void PrintTo(Utils::SmallStringView text, ::std::ostream *os)
{
*os << "\"" << text << "\"";
@@ -1061,7 +1157,15 @@ std::ostream &operator<<(std::ostream &out, const PchCreatorIncludes &includes)
std::ostream &operator<<(std::ostream &out, const PchTask &task)
{
return out << "(" << task.projectPartIds << ", " << task.includes << ", " << task.compilerMacros
- << ", " << task.usedMacros << ")";
+ << ", " << task.usedMacros << ", " << toText(task.language) << ", "
+ << task.systemIncludeSearchPaths << ", " << task.projectIncludeSearchPaths << ", "
+ << task.toolChainArguments << ", " << toText(task.languageVersion) << ", "
+ << toText(task.languageExtension) << ")";
+}
+
+std::ostream &operator<<(std::ostream &out, const PchTaskSet &taskSet)
+{
+ return out << "(" << taskSet.system << ", " << taskSet.project << ")";
}
std::ostream &operator<<(std::ostream &out, const BuildDependency &dependency)
@@ -1105,6 +1209,50 @@ std::ostream &operator<<(std::ostream &out, const SourceEntry &entry)
return out << "(" << entry.sourceId << ", " << sourceTypeString(entry.sourceType) << ")";
}
+const char *typeToString(IncludeSearchPathType type)
+{
+ switch (type) {
+ case IncludeSearchPathType::Invalid:
+ return "Invalid";
+ case IncludeSearchPathType::User:
+ return "User";
+ case IncludeSearchPathType::System:
+ return "System";
+ case IncludeSearchPathType::BuiltIn:
+ return "BuiltIn";
+ case IncludeSearchPathType::Framework:
+ return "Framework";
+ }
+
+ return nullptr;
+}
+
+std::ostream &operator<<(std::ostream &out, const IncludeSearchPathType &pathType)
+{
+ return out << "IncludeSearchPathType::" << typeToString(pathType);
+}
+
+std::ostream &operator<<(std::ostream &out, const IncludeSearchPath &path)
+{
+ return out << "(" << path.path << ", " << path.index << ", " << typeToString(path.type) << ")";
+}
+
+std::ostream &operator<<(std::ostream &out, const ArgumentsEntry &entry)
+{
+ return out << "(" << entry.ids << ", " << entry.arguments << ")";
+}
+
+std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container)
+{
+ out << "(" << container.projectPartId << ", " << container.toolChainArguments << ", "
+ << container.headerPathIds << ", " << container.sourcePathIds << ", "
+ << container.compilerMacros << ", " << container.systemIncludeSearchPaths << ", "
+ << container.projectIncludeSearchPaths << ", " << toText(container.language) << ", "
+ << toText(container.languageVersion) << ", " << toText(container.languageExtension) << ")";
+
+ return out;
+}
+
void PrintTo(const FilePath &filePath, ::std::ostream *os)
{
*os << filePath;
@@ -1138,19 +1286,6 @@ std::ostream &operator<<(std::ostream &os, const FileContainer &container)
return os;
}
-std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container)
-{
- out << "("
- << container.projectPartId << ", "
- << container.arguments << ", "
- << container.headerPathIds << ", "
- << container.sourcePathIds << ", "
- << container.compilerMacros << ", "
- << container.includeSearchPaths << ")";
-
- return out;
-}
-
std::ostream &operator<<(std::ostream &os, const SourceLocationContainer &container)
{
os << "("
diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h
index 0f2184fc11..ec54af3085 100644
--- a/tests/unit/unittest/gtest-creator-printing.h
+++ b/tests/unit/unittest/gtest-creator-printing.h
@@ -25,6 +25,7 @@
#pragma once
+#include <utils/cpplanguage_details.h>
#include <utils/smallstringio.h>
#include <utils/optional.h>
@@ -74,6 +75,9 @@ class LineColumn;
class SmallStringView;
std::ostream &operator<<(std::ostream &out, const LineColumn &lineColumn);
+std::ostream &operator<<(std::ostream &out, const Utils::Language &language);
+std::ostream &operator<<(std::ostream &out, const Utils::LanguageVersion &languageVersion);
+std::ostream &operator<<(std::ostream &out, const Utils::LanguageExtension &languageExtension);
template <typename Type>
std::ostream &operator<<(std::ostream &out, const Utils::optional<Type> &optional)
@@ -176,10 +180,15 @@ class SymbolIndexerTask;
class ProgressMessage;
class PchCreatorIncludes;
class PchTask;
+class PchTaskSet;
class BuildDependency;
class SourceEntry;
class FilePathCaching;
class SlotUsage;
+class IncludeSearchPath;
+enum class IncludeSearchPathType : unsigned char;
+class ArgumentsEntry;
+class ProjectPartContainer;
std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry);
std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths);
@@ -262,9 +271,14 @@ std::ostream &operator<<(std::ostream &out, const SymbolIndexerTask &task);
std::ostream &operator<<(std::ostream &out, const ProgressMessage &message);
std::ostream &operator<<(std::ostream &out, const PchCreatorIncludes &includes);
std::ostream &operator<<(std::ostream &out, const PchTask &task);
+std::ostream &operator<<(std::ostream &out, const PchTaskSet &taskSet);
std::ostream &operator<<(std::ostream &out, const BuildDependency &dependency);
std::ostream &operator<<(std::ostream &out, const SourceEntry &entry);
std::ostream &operator<<(std::ostream &out, const SlotUsage &slotUsage);
+std::ostream &operator<<(std::ostream &out, const IncludeSearchPathType &pathType);
+std::ostream &operator<<(std::ostream &out, const IncludeSearchPath &path);
+std::ostream &operator<<(std::ostream &out, const ArgumentsEntry &entry);
+std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container);
void PrintTo(const FilePath &filePath, ::std::ostream *os);
void PrintTo(const FilePathView &filePathView, ::std::ostream *os);
@@ -272,12 +286,10 @@ void PrintTo(const FilePathId &filePathId, ::std::ostream *os);
namespace V2 {
class FileContainer;
-class ProjectPartContainer;
class SourceRangeContainer;
class SourceLocationContainer;
std::ostream &operator<<(std::ostream &out, const FileContainer &container);
-std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container);
std::ostream &operator<<(std::ostream &out, const SourceLocationContainer &container);
std::ostream &operator<<(std::ostream &out, const SourceRangeContainer &container);
} // namespace V2
diff --git a/tests/unit/unittest/mockbuilddependenciesprovider.h b/tests/unit/unittest/mockbuilddependenciesprovider.h
index 2a1fd8f93f..a4a57db33b 100644
--- a/tests/unit/unittest/mockbuilddependenciesprovider.h
+++ b/tests/unit/unittest/mockbuilddependenciesprovider.h
@@ -34,5 +34,5 @@ class MockBuildDependenciesProvider : public ClangBackEnd::BuildDependenciesProv
public:
MOCK_METHOD1(
create,
- ClangBackEnd::BuildDependency(const ClangBackEnd::V2::ProjectPartContainer &projectPart));
+ ClangBackEnd::BuildDependency(const ClangBackEnd::ProjectPartContainer &projectPart));
};
diff --git a/tests/unit/unittest/mockbuilddependencygenerator.h b/tests/unit/unittest/mockbuilddependencygenerator.h
index 91b8a1422d..abd6c223d0 100644
--- a/tests/unit/unittest/mockbuilddependencygenerator.h
+++ b/tests/unit/unittest/mockbuilddependencygenerator.h
@@ -33,6 +33,6 @@ class MockBuildDependencyGenerator : public ClangBackEnd::BuildDependencyGenerat
{
public:
MOCK_METHOD1(create,
- ClangBackEnd::BuildDependency (const ClangBackEnd::V2::ProjectPartContainer &projectPart));
+ ClangBackEnd::BuildDependency (const ClangBackEnd::ProjectPartContainer &projectPart));
};
diff --git a/tests/unit/unittest/mockpchcreator.h b/tests/unit/unittest/mockpchcreator.h
index 992976d4de..86a34ac04f 100644
--- a/tests/unit/unittest/mockpchcreator.h
+++ b/tests/unit/unittest/mockpchcreator.h
@@ -30,18 +30,21 @@
#include <filecontainerv2.h>
#include <pchcreatorinterface.h>
#include <projectpartpch.h>
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
class MockPchCreator : public ClangBackEnd::PchCreatorInterface
{
public:
- MOCK_METHOD1(generatePchDeprecated, void(const ClangBackEnd::V2::ProjectPartContainer &projectPart));
MOCK_METHOD1(generatePch, void(const ClangBackEnd::PchTask &pchTask));
- MOCK_METHOD0(takeProjectIncludes, ClangBackEnd::IdPaths());
MOCK_METHOD0(projectPartPch, const ClangBackEnd::ProjectPartPch &());
MOCK_METHOD1(setUnsavedFiles, void(const ClangBackEnd::V2::FileContainers &fileContainers));
MOCK_METHOD0(clear, void());
MOCK_METHOD0(doInMainThreadAfterFinished, void());
MOCK_CONST_METHOD0(isUsed, bool());
MOCK_METHOD1(setIsUsed, void(bool));
+
+ void generatePch(ClangBackEnd::PchTask &&pchTask) override
+ {
+ generatePch(pchTask);
+ }
};
diff --git a/tests/unit/unittest/mockpchtaskgenerator.h b/tests/unit/unittest/mockpchtaskgenerator.h
new file mode 100644
index 0000000000..4934d7a9a6
--- /dev/null
+++ b/tests/unit/unittest/mockpchtaskgenerator.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#pragma once
+
+#include "googletest.h"
+
+#include <pchtaskgeneratorinterface.h>
+
+class MockPchTaskGenerator : public ClangBackEnd::PchTaskGeneratorInterface
+{
+public:
+ MOCK_METHOD2(addProjectParts,
+ void(const ClangBackEnd::ProjectPartContainers &projectParts,
+ const Utils::SmallStringVector &toolChainArguments));
+ MOCK_METHOD1(removeProjectParts,
+ void (const Utils::SmallStringVector &projectsPartIds));
+
+ void addProjectParts(ClangBackEnd::ProjectPartContainers &&projectParts,
+ Utils::SmallStringVector &&toolChainArguments) override
+ {
+ addProjectParts(projectParts, toolChainArguments);
+ }
+};
diff --git a/tests/unit/unittest/mockpchtasksmerger.h b/tests/unit/unittest/mockpchtasksmerger.h
index c320159d34..39e73f9f55 100644
--- a/tests/unit/unittest/mockpchtasksmerger.h
+++ b/tests/unit/unittest/mockpchtasksmerger.h
@@ -32,7 +32,15 @@
class MockPchTasksMerger : public ClangBackEnd::PchTasksMergerInterface
{
public:
- MOCK_METHOD1(mergeTasks, void(const ClangBackEnd::PchTaskSets &pchTaskSets));
+ MOCK_METHOD2(mergeTasks,
+ void(const ClangBackEnd::PchTaskSets &pchTaskSets,
+ const Utils::SmallStringVector &toolChainArguments));
- void mergeTasks(ClangBackEnd::PchTaskSets &&pchTaskSets) override { mergeTasks(pchTaskSets); }
+ MOCK_METHOD1(removePchTasks, void(const Utils::SmallStringVector &projectPartIds));
+
+ void mergeTasks(ClangBackEnd::PchTaskSets &&pchTaskSets,
+ Utils::SmallStringVector &&toolChainArguments) override
+ {
+ mergeTasks(pchTaskSets, toolChainArguments);
+ }
};
diff --git a/tests/unit/unittest/mockprecompiledheaderstorage.h b/tests/unit/unittest/mockprecompiledheaderstorage.h
index c267ecb535..a2bc0fddf0 100644
--- a/tests/unit/unittest/mockprecompiledheaderstorage.h
+++ b/tests/unit/unittest/mockprecompiledheaderstorage.h
@@ -37,11 +37,12 @@ public:
Utils::SmallStringView pchPath,
long long pchBuildTime));
MOCK_METHOD1(deleteProjectPrecompiledHeader, void(Utils::SmallStringView projectPartName));
- MOCK_METHOD3(insertSystemPrecompiledHeader,
- void(Utils::SmallStringView projectPartName,
+ MOCK_METHOD3(insertSystemPrecompiledHeaders,
+ void(const Utils::SmallStringVector &projectPartNames,
Utils::SmallStringView pchPath,
long long pchBuildTime));
- MOCK_METHOD1(deleteSystemPrecompiledHeader, void(Utils::SmallStringView projectPartName));
+ MOCK_METHOD1(deleteSystemPrecompiledHeaders,
+ void(const Utils::SmallStringVector &projectPartNames));
MOCK_METHOD1(fetchSystemPrecompiledHeaderPath,
- Utils::PathString(Utils::SmallStringView projectPartName));
+ ClangBackEnd::FilePath(Utils::SmallStringView projectPartName));
};
diff --git a/tests/unit/unittest/mockprojectpartqueue.h b/tests/unit/unittest/mockprojectpartqueue.h
index 8d1ec1f66c..022878c73a 100644
--- a/tests/unit/unittest/mockprojectpartqueue.h
+++ b/tests/unit/unittest/mockprojectpartqueue.h
@@ -33,13 +33,13 @@ class MockProjectPartQueue : public ClangBackEnd::ProjectPartQueueInterface
{
public:
MOCK_METHOD1(addProjectParts,
- void (const ClangBackEnd::V2::ProjectPartContainers &projectParts));
+ void (const ClangBackEnd::ProjectPartContainers &projectParts));
MOCK_METHOD1(removeProjectParts,
void (const Utils::SmallStringVector &projectsPartIds));
MOCK_METHOD0(processEntries, void ());
- void addProjectParts(ClangBackEnd::V2::ProjectPartContainers &&projectParts) override
+ void addProjectParts(ClangBackEnd::ProjectPartContainers &&projectParts) override
{
addProjectParts(projectParts);
}
diff --git a/tests/unit/unittest/mockprojectparts.h b/tests/unit/unittest/mockprojectparts.h
index 611e12b9fe..f81eabc91c 100644
--- a/tests/unit/unittest/mockprojectparts.h
+++ b/tests/unit/unittest/mockprojectparts.h
@@ -33,13 +33,13 @@ class MockProjectParts : public ClangBackEnd::ProjectPartsInterface
{
public:
MOCK_METHOD1(update,
- ClangBackEnd::V2::ProjectPartContainers(const ClangBackEnd::V2::ProjectPartContainers &projectsParts));
+ ClangBackEnd::ProjectPartContainers(const ClangBackEnd::ProjectPartContainers &projectsParts));
MOCK_METHOD1(remove,
void(const Utils::SmallStringVector &projectPartIds));
MOCK_CONST_METHOD1(projects,
- ClangBackEnd::V2::ProjectPartContainers(const Utils::SmallStringVector &projectPartIds));
+ ClangBackEnd::ProjectPartContainers(const Utils::SmallStringVector &projectPartIds));
- ClangBackEnd::V2::ProjectPartContainers update(ClangBackEnd::V2::ProjectPartContainers &&projectsParts) override
+ ClangBackEnd::ProjectPartContainers update(ClangBackEnd::ProjectPartContainers &&projectsParts) override
{
return update(projectsParts);
}
diff --git a/tests/unit/unittest/mocksqlitereadstatement.cpp b/tests/unit/unittest/mocksqlitereadstatement.cpp
index 128b3d899f..79fb9879b7 100644
--- a/tests/unit/unittest/mocksqlitereadstatement.cpp
+++ b/tests/unit/unittest/mocksqlitereadstatement.cpp
@@ -145,15 +145,22 @@ MockSqliteReadStatement::value<Utils::PathString>(const Utils::SmallStringView &
}
template <>
+Utils::optional<ClangBackEnd::FilePath>
+MockSqliteReadStatement::value<ClangBackEnd::FilePath>(const Utils::SmallStringView &path)
+{
+ return valueReturnFilePath(path);
+}
+
+template <>
Utils::optional<ClangBackEnd::ProjectPartArtefact>
-MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const int& sourceId)
+MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 5>(const int& sourceId)
{
return valueReturnProjectPartArtefact(sourceId);
}
template <>
Utils::optional<ClangBackEnd::ProjectPartArtefact>
-MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const Utils::SmallStringView &projectPartName)
+MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 5>(const Utils::SmallStringView &projectPartName)
{
return valueReturnProjectPartArtefact(projectPartName);
}
diff --git a/tests/unit/unittest/mocksqlitereadstatement.h b/tests/unit/unittest/mocksqlitereadstatement.h
index 4fbdda2a6d..a5c15e46b7 100644
--- a/tests/unit/unittest/mocksqlitereadstatement.h
+++ b/tests/unit/unittest/mocksqlitereadstatement.h
@@ -99,6 +99,9 @@ public:
MOCK_METHOD1(valueReturnPathString,
Utils::optional<Utils::PathString>(Utils::SmallStringView));
+ MOCK_METHOD1(valueReturnFilePath,
+ Utils::optional<ClangBackEnd::FilePath>(Utils::SmallStringView));
+
MOCK_METHOD1(valueReturnSmallString,
Utils::optional<Utils::SmallString>(int));
@@ -213,6 +216,10 @@ Utils::optional<int>
MockSqliteReadStatement::value<int>(const Utils::PathString&);
template <>
+Utils::optional<ClangBackEnd::FilePath>
+MockSqliteReadStatement::value<ClangBackEnd::FilePath>(const Utils::SmallStringView&);
+
+template <>
Utils::optional<int>
MockSqliteReadStatement::value<int>(const int&, const Utils::SmallStringView&);
@@ -230,11 +237,11 @@ MockSqliteReadStatement::value<Utils::PathString>(const Utils::SmallStringView&)
template <>
Utils::optional<ClangBackEnd::ProjectPartArtefact>
-MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const int&);
+MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 5>(const int&);
template <>
Utils::optional<ClangBackEnd::ProjectPartArtefact>
-MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const int&);
+MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 5>(const int&);
template <>
Utils::optional<ClangBackEnd::ProjectPartPch>
diff --git a/tests/unit/unittest/mocksqlitewritestatement.h b/tests/unit/unittest/mocksqlitewritestatement.h
index 8da4db8ef5..7e2cb0270a 100644
--- a/tests/unit/unittest/mocksqlitewritestatement.h
+++ b/tests/unit/unittest/mocksqlitewritestatement.h
@@ -78,6 +78,12 @@ public:
Utils::SmallStringView,
Utils::SmallStringView));
+ MOCK_METHOD5(write,
+ void (Utils::SmallStringView,
+ Utils::SmallStringView,
+ Utils::SmallStringView,
+ Utils::SmallStringView,
+ Utils::SmallStringView));
MOCK_METHOD1(write,
void (Utils::SmallStringView));
diff --git a/tests/unit/unittest/mocksymbolindexing.h b/tests/unit/unittest/mocksymbolindexing.h
index 048840d976..c502f62d77 100644
--- a/tests/unit/unittest/mocksymbolindexing.h
+++ b/tests/unit/unittest/mocksymbolindexing.h
@@ -33,9 +33,9 @@ class MockSymbolIndexing : public ClangBackEnd::SymbolIndexingInterface
{
public:
MOCK_METHOD1(updateProjectParts,
- void(const ClangBackEnd::V2::ProjectPartContainers &projectParts));
+ void(const ClangBackEnd::ProjectPartContainers &projectParts));
- void updateProjectParts(ClangBackEnd::V2::ProjectPartContainers &&projectParts) override
+ void updateProjectParts(ClangBackEnd::ProjectPartContainers &&projectParts) override
{
updateProjectParts(projectParts);
}
diff --git a/tests/unit/unittest/mocksymbolstorage.h b/tests/unit/unittest/mocksymbolstorage.h
index c9de142bd4..5b2451bf5a 100644
--- a/tests/unit/unittest/mocksymbolstorage.h
+++ b/tests/unit/unittest/mocksymbolstorage.h
@@ -37,11 +37,12 @@ public:
MOCK_METHOD2(addSymbolsAndSourceLocations,
void(const ClangBackEnd::SymbolEntries &symbolEentries,
const ClangBackEnd::SourceLocationEntries &sourceLocations));
- MOCK_METHOD4(insertOrUpdateProjectPart,
+ MOCK_METHOD5(insertOrUpdateProjectPart,
int(Utils::SmallStringView projectPartName,
const Utils::SmallStringVector &commandLineArgument,
const ClangBackEnd::CompilerMacros &compilerMacros,
- const Utils::SmallStringVector &includeSearchPaths));
+ const ClangBackEnd::IncludeSearchPaths &systemIncludeSearchPaths,
+ const ClangBackEnd::IncludeSearchPaths &projectIncludeSearchPaths));
MOCK_METHOD2(updateProjectPartSources,
void(int projectPartId,
const ClangBackEnd::FilePathIds &sourceFilePathIds));
diff --git a/tests/unit/unittest/modifiedtimechecker-test.cpp b/tests/unit/unittest/modifiedtimechecker-test.cpp
new file mode 100644
index 0000000000..8e0c881b38
--- /dev/null
+++ b/tests/unit/unittest/modifiedtimechecker-test.cpp
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <filepathcaching.h>
+#include <modifiedtimechecker.h>
+#include <refactoringdatabaseinitializer.h>
+
+namespace {
+
+using ClangBackEnd::SourceEntries;
+using ClangBackEnd::SourceType;
+using ClangBackEnd::FilePathView;
+
+
+class ModifiedTimeChecker : public testing::Test
+{
+protected:
+
+ ClangBackEnd::FilePathId id(const Utils::SmallStringView &path) const
+ {
+ return filePathCache.filePathId(ClangBackEnd::FilePathView{path});
+ }
+
+
+ ModifiedTimeChecker()
+ {
+ ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path1")))).WillByDefault(Return(50));
+ ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path2")))).WillByDefault(Return(30));
+ }
+ NiceMock<MockFunction<ClangBackEnd::TimeStamp(ClangBackEnd::FilePathView filePath)>> getModifiedTimeCallback;
+ Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
+ ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database};
+ ClangBackEnd::FilePathCaching filePathCache{database};
+ decltype(getModifiedTimeCallback.AsStdFunction()) callback = getModifiedTimeCallback
+ .AsStdFunction();
+ ClangBackEnd::ModifiedTimeChecker checker{callback, filePathCache};
+ SourceEntries upToDateEntries = {{id("/path1"), SourceType::UserInclude, 100},
+ {id("/path2"), SourceType::SystemInclude, 30}};
+ SourceEntries notUpToDateEntries = {{id("/path1"), SourceType::UserInclude, 50},
+ {id("/path2"), SourceType::SystemInclude, 20}};
+};
+
+TEST_F(ModifiedTimeChecker, IsUpToDate)
+{
+ auto isUpToDate = checker.isUpToDate(upToDateEntries);
+
+ ASSERT_TRUE(isUpToDate);
+}
+
+TEST_F(ModifiedTimeChecker, IsNotUpToDateIfSourceEntriesAreEmpty)
+{
+ auto isUpToDate = checker.isUpToDate({});
+
+ ASSERT_FALSE(isUpToDate);
+}
+
+TEST_F(ModifiedTimeChecker, IsNotUpToDate)
+{
+ auto isUpToDate = checker.isUpToDate({});
+
+ ASSERT_FALSE(isUpToDate);
+}
+
+TEST_F(ModifiedTimeChecker, PathChangesUpdatesTimeStamps)
+{
+ checker.isUpToDate(upToDateEntries);
+
+ EXPECT_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path1"))));
+ EXPECT_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path2"))));
+
+ checker.pathsChanged({id(FilePathView("/path1")), id(FilePathView("/path2")), id(FilePathView("/path3"))});
+}
+
+TEST_F(ModifiedTimeChecker, IsNotUpToDateAnyMoreAfterUpdating)
+{
+ checker.isUpToDate(upToDateEntries);
+ ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path1")))).WillByDefault(Return(120));
+ ON_CALL(getModifiedTimeCallback, Call(Eq(FilePathView("/path2")))).WillByDefault(Return(30));
+
+ checker.pathsChanged({id(FilePathView("/path1")), id(FilePathView("/path2")), id(FilePathView("/path3"))});
+
+ ASSERT_FALSE(checker.isUpToDate(upToDateEntries));
+}
+
+} // namespace
diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp
index 8b556af6b7..68c67ecdd5 100644
--- a/tests/unit/unittest/pchcreator-test.cpp
+++ b/tests/unit/unittest/pchcreator-test.cpp
@@ -50,22 +50,25 @@ using ClangBackEnd::FilePathIds;
using ClangBackEnd::FilePathView;
using ClangBackEnd::GeneratedFiles;
using ClangBackEnd::IdPaths;
+using ClangBackEnd::IncludeSearchPathType;
+using ClangBackEnd::PchTask;
using ClangBackEnd::ProjectPartPch;
using ClangBackEnd::SourceEntries;
using ClangBackEnd::SourceEntry;
using ClangBackEnd::SourceType;
using ClangBackEnd::V2::FileContainer;
-using ClangBackEnd::V2::ProjectPartContainer;
+using ClangBackEnd::ProjectPartContainer;
using Utils::PathString;
using Utils::SmallString;
using UnitTests::EndsWith;
-MATCHER_P2(HasIdAndType, sourceId, sourceType,
- std::string(negation ? "hasn't" : "has") +
- PrintToString(ClangBackEnd::SourceEntry(sourceId, sourceType,
- -1)))
+MATCHER_P2(HasIdAndType,
+ sourceId,
+ sourceType,
+ std::string(negation ? "hasn't" : "has")
+ + PrintToString(ClangBackEnd::SourceEntry(sourceId, sourceType, -1)))
{
const ClangBackEnd::SourceEntry &entry = arg;
return entry.sourceId == sourceId && entry.sourceType == sourceType;
@@ -74,7 +77,7 @@ MATCHER_P2(HasIdAndType, sourceId, sourceType,
class PchCreator: public ::testing::Test
{
protected:
- void SetUp()
+ PchCreator()
{
creator.setUnsavedFiles({generatedFile});
}
@@ -96,86 +99,26 @@ protected:
TestEnvironment environment;
FileContainer generatedFile{{TESTDATA_DIR, generatedFileName}, "#pragma once", {}};
NiceMock<MockPchManagerClient> mockPchManagerClient;
- NiceMock<MockClangPathWatcher> mockClangPathWatcher;
- ClangBackEnd::PchCreator creator{environment, database, mockPchManagerClient, mockClangPathWatcher};
- ProjectPartContainer projectPart1{"project1",
- {"-I", TESTDATA_DIR, "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system", "-Wno-pragma-once-outside-header"},
- {{"DEFINE", "1", 1}},
- {TESTDATA_DIR "/builddependencycollector/external", TESTDATA_DIR "/builddependencycollector/project"},
- {id(header1Path)},
- {id(main1Path)}};
- ProjectPartContainer projectPart2{"project2",
- {"-I", TESTDATA_DIR, "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-x", "c++-header", "-Wno-pragma-once-outside-header"},
- {{"DEFINE", "1", 1}},
- {TESTDATA_DIR "/builddependencycollector/external", TESTDATA_DIR "/builddependencycollector/project"},
- {id(header2Path)},
- {id(main2Path)}};
+ ClangBackEnd::PchCreator creator{environment, database, mockPchManagerClient};
+ PchTask pchTask1{
+ "project1",
+ {id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external1.h"),
+ id(TESTDATA_DIR "/builddependencycollector/external/external2.h")},
+ {},
+ {},
+ {},
+ {{TESTDATA_DIR "/builddependencycollector/system", 2, IncludeSearchPathType::BuiltIn},
+ {TESTDATA_DIR "/builddependencycollector/external", 1, IncludeSearchPathType::System}},
+ {{TESTDATA_DIR "/builddependencycollector/project", 1, IncludeSearchPathType::User}},
+ };
};
using PchCreatorSlowTest = PchCreator;
using PchCreatorVerySlowTest = PchCreator;
-TEST_F(PchCreator, ConvertToQStringList)
+TEST_F(PchCreator, CreateProjectPartPchFileContent)
{
- auto arguments = creator.convertToQStringList({"-I", TESTDATA_DIR});
-
- ASSERT_THAT(arguments, ElementsAre(QString("-I"), QString(TESTDATA_DIR)));
-}
-
-TEST_F(PchCreator, CreateProjectPartCommandLine)
-{
- auto commandLine = creator.generateProjectPartCommandLine(projectPart1);
-
- ASSERT_THAT(commandLine, ElementsAre(environment.clangCompilerPath(), "-I", TESTDATA_DIR, "-I", TESTDATA_DIR "/builddependencycollector/external", "-I", TESTDATA_DIR "/builddependencycollector/project", "-isystem", TESTDATA_DIR "/builddependencycollector/system", "-Wno-pragma-once-outside-header"));
-}
-
-TEST_F(PchCreator, CreateProjectPartHeaders)
-{
- auto includeIds = creator.generateProjectPartHeaders(projectPart1);
-
- ASSERT_THAT(includeIds, UnorderedElementsAre(header1Path, generatedFilePath));
-}
-
-TEST_F(PchCreator, CreateProjectPartSources)
-{
- auto includeIds = creator.generateProjectPartSourcePaths(projectPart1);
-
- ASSERT_THAT(includeIds, UnorderedElementsAre(main1Path));
-}
-
-TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludes)
-{
- using ClangBackEnd::PchCreatorIncludes;
-
- auto includeIds = creator.generateProjectPartPchIncludes(projectPart1);
-
- ASSERT_THAT(
- includeIds,
- AllOf(
- Contains(HasIdAndType(
- id(TESTDATA_DIR "/builddependencycollector/project/header2.h"),
- SourceType::TopProjectInclude)),
- Contains(HasIdAndType(
- id(TESTDATA_DIR "/builddependencycollector/system/system1.h"),
- SourceType::TopSystemInclude)),
- Contains(HasIdAndType(
- id(TESTDATA_DIR
- "/builddependencycollector/system/indirect_system.h"),
- SourceType::SystemInclude)),
- Contains(HasIdAndType(
- id(TESTDATA_DIR
- "/builddependencycollector/external/external1.h"),
- SourceType::TopProjectInclude)),
- Contains(HasIdAndType(
- id(TESTDATA_DIR
- "/builddependencycollector/external/external2.h"),
- SourceType::TopProjectInclude))));
-}
-
-TEST_F(PchCreatorSlowTest, CreateProjectPartPchFileContent)
-{
- auto includes = creator.generateProjectPartPchIncludes(projectPart1);
-
- auto content = creator.generatePchIncludeFileContent(creator.topIncludeIds(includes));
+ auto content = creator.generatePchIncludeFileContent(pchTask1.includes);
ASSERT_THAT(std::string(content),
AllOf(HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/project/header2.h\"\n"),
@@ -183,11 +126,10 @@ TEST_F(PchCreatorSlowTest, CreateProjectPartPchFileContent)
HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external2.h\"\n")));
}
-TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludeFile)
+TEST_F(PchCreator, CreatePchIncludeFile)
{
- auto includes = creator.generateProjectPartPchIncludes(projectPart1);
- auto content = creator.generatePchIncludeFileContent(creator.topIncludeIds(includes));
- auto pchIncludeFilePath = creator.generateProjectPathPchHeaderFilePath(projectPart1);
+ auto content = creator.generatePchIncludeFileContent(pchTask1.includes);
+ auto pchIncludeFilePath = creator.generatePchHeaderFilePath();
auto file = creator.generateFileWithContent(pchIncludeFilePath, content);
file->open(QIODevice::ReadOnly);
@@ -199,38 +141,63 @@ TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludeFile)
HasSubstr("#include \"" TESTDATA_DIR "/builddependencycollector/external/external2.h\"\n")));
}
-TEST_F(PchCreator, CreateProjectPartPchCompilerArguments)
-{
- auto arguments = creator.generateProjectPartPchCompilerArguments(projectPart1);
-
- ASSERT_THAT(arguments, AllOf(Contains("-x"),
- Contains("c++-header"),
- Contains("-Xclang"),
- Contains("-emit-pch"),
- Contains("-o"),
- Contains(EndsWith(".pch"))));
-}
-
TEST_F(PchCreator, CreateProjectPartClangCompilerArguments)
{
- auto arguments = creator.generateProjectPartClangCompilerArguments(projectPart1);
-
- ASSERT_THAT(arguments, AllOf(Contains(TESTDATA_DIR),
- Contains("-emit-pch"),
- Contains("-o"),
- Not(Contains(environment.clangCompilerPath()))));
-}
-
-TEST_F(PchCreatorVerySlowTest, IncludesForCreatePchsForProjectParts)
-{
- creator.generatePchDeprecated(projectPart1);
-
- ASSERT_THAT(creator.takeProjectIncludes().id, "project1");
+ auto arguments = creator.generateClangCompilerArguments(std::move(pchTask1),
+ "project.h",
+ "project.pch");
+
+ ASSERT_THAT(arguments,
+ ElementsAre("clang++",
+ "-x",
+ "c++-header",
+ "-std=c++98",
+ "-nostdinc",
+ "-nostdlibinc",
+ "-I",
+ TESTDATA_DIR "/builddependencycollector/project",
+ "-isystem",
+ TESTDATA_DIR "/builddependencycollector/external",
+ "-isystem",
+ TESTDATA_DIR "/builddependencycollector/system",
+ "-o",
+ "project.pch",
+ "project.h"));
+}
+
+TEST_F(PchCreator, CreateProjectPartClangCompilerArgumentsWithSystemPch)
+{
+ pchTask1.systemPchPath = "system.pch";
+
+ auto arguments = creator.generateClangCompilerArguments(std::move(pchTask1),
+ "project.h",
+ "project.pch");
+
+ ASSERT_THAT(arguments,
+ ElementsAre("clang++",
+ "-x",
+ "c++-header",
+ "-std=c++98",
+ "-nostdinc",
+ "-nostdlibinc",
+ "-I",
+ TESTDATA_DIR "/builddependencycollector/project",
+ "-isystem",
+ TESTDATA_DIR "/builddependencycollector/external",
+ "-isystem",
+ TESTDATA_DIR "/builddependencycollector/system",
+ "-Xclang",
+ "-include-pch",
+ "-Xclang",
+ "system.pch",
+ "-o",
+ "project.pch",
+ "project.h"));
}
TEST_F(PchCreatorVerySlowTest, ProjectPartPchsSendToPchManagerClient)
{
- creator.generatePchDeprecated(projectPart1);
+ creator.generatePch(std::move(pchTask1));
EXPECT_CALL(mockPchManagerClient,
precompiledHeadersUpdated(
@@ -240,30 +207,10 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchsSendToPchManagerClient)
creator.doInMainThreadAfterFinished();
}
-TEST_F(PchCreatorVerySlowTest, UpdateFileWatcherIncludes)
-{
- creator.generatePchDeprecated(projectPart1);
-
- EXPECT_CALL(mockClangPathWatcher,
- updateIdPaths(ElementsAre(creator.projectIncludes())));
-
- creator.doInMainThreadAfterFinished();
-}
-TEST_F(PchCreatorVerySlowTest, IdPathsForCreatePchsForProjectParts)
+TEST_F(PchCreatorVerySlowTest, ProjectPartPchForCreatesPchForPchTask)
{
- creator.generatePchDeprecated(projectPart1);
-
- ASSERT_THAT(creator.takeProjectIncludes(),
- AllOf(Field(&IdPaths::id, "project1"),
- Field(&IdPaths::filePathIds, AllOf(Contains(id(TESTDATA_DIR "/builddependencycollector/project/header2.h")),
- Contains(id(TESTDATA_DIR "/builddependencycollector/external/external1.h")),
- Contains(id(TESTDATA_DIR "/builddependencycollector/external/external2.h"))))));
-}
-
-TEST_F(PchCreatorVerySlowTest, ProjectPartPchForCreatesPchForProjectPart)
-{
- creator.generatePchDeprecated(projectPart1);
+ creator.generatePch(std::move(pchTask1));
ASSERT_THAT(creator.projectPartPch(),
AllOf(Field(&ProjectPartPch::projectPartId, Eq("project1")),
@@ -273,52 +220,29 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchForCreatesPchForProjectPart)
TEST_F(PchCreatorVerySlowTest, ProjectPartPchCleared)
{
- creator.generatePchDeprecated(projectPart1);
+ creator.generatePch(std::move(pchTask1));
creator.clear();
ASSERT_THAT(creator.projectPartPch(), ClangBackEnd::ProjectPartPch{});
}
-
-TEST_F(PchCreatorVerySlowTest, ProjectIncludesCleared)
-{
- creator.generatePchDeprecated(projectPart1);
-
- creator.clear();
-
- ASSERT_THAT(creator.projectIncludes(), ClangBackEnd::IdPaths{});
-}
-
-TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesNoPchForProjectPart)
+TEST_F(PchCreatorVerySlowTest, FaultyProjectPartPchForCreatesFaultyPchForPchTask)
{
- ProjectPartContainer faultyProjectPart{"faultyProject",
- {"-I", TESTDATA_DIR},
- {{"DEFINE", "1", 1}},
- {"/includes"},
- {},
- {id(TESTDATA_DIR "/builddependencycollector/project/faulty.cpp")}};
+ PchTask faultyPchTask{"faultyProjectPart",
+ {id(TESTDATA_DIR "/builddependencycollector/project/faulty.cpp")},
+ {{"DEFINE", "1", 1}},
+ {},
+ {},
+ {{TESTDATA_DIR "/builddependencycollector/external", 1, IncludeSearchPathType::System}},
+ {{TESTDATA_DIR "/builddependencycollector/project", 1, IncludeSearchPathType::User}}};
- creator.generatePchDeprecated(faultyProjectPart);
+ creator.generatePch(std::move(faultyPchTask));
ASSERT_THAT(creator.projectPartPch(),
- AllOf(Field(&ProjectPartPch::projectPartId, Eq("faultyProject")),
+ AllOf(Field(&ProjectPartPch::projectPartId, Eq("faultyProjectPart")),
Field(&ProjectPartPch::pchPath, IsEmpty()),
Field(&ProjectPartPch::lastModified, Eq(-1))));
}
-TEST_F(PchCreator, CreateProjectPartSourcesContent)
-{
- auto content = creator.generateProjectPartSourcesContent(projectPart1);
-
- ASSERT_THAT(content, Eq("#include \"" TESTDATA_DIR "/builddependencycollector/project/main3.cpp\"\n"));
-}
-
-TEST_F(PchCreator, Call)
-{
- auto content = creator.generateProjectPartSourcesContent(projectPart1);
-
- ASSERT_THAT(content, Eq("#include \"" TESTDATA_DIR "/builddependencycollector/project/main3.cpp\"\n"));
-}
-
}
diff --git a/tests/unit/unittest/pchmanagerclient-test.cpp b/tests/unit/unittest/pchmanagerclient-test.cpp
index cec39fc73e..d35e595b04 100644
--- a/tests/unit/unittest/pchmanagerclient-test.cpp
+++ b/tests/unit/unittest/pchmanagerclient-test.cpp
@@ -62,10 +62,10 @@ protected:
ClangBackEnd::FilePathCaching filePathCache{database};
ClangPchManager::PchManagerProjectUpdater projectUpdater{mockPchManagerServer, client, filePathCache};
Utils::SmallString projectPartId{"projectPartId"};
- Utils::SmallString pchFilePath{"/path/to/pch"};
+ ClangBackEnd::FilePath pchFilePath{"/path/to/pch"};
PrecompiledHeadersUpdatedMessage message{{{projectPartId.clone(), pchFilePath.clone(), 1}}};
Utils::SmallString projectPartId2{"projectPartId2"};
- Utils::SmallString pchFilePath2{"/path/to/pch2"};
+ ClangBackEnd::FilePath pchFilePath2{"/path/to/pch2"};
PrecompiledHeadersUpdatedMessage message2{{{projectPartId2.clone(), pchFilePath2.clone(), 1}}};
};
diff --git a/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp
index 13a4ad3437..a16b3981e4 100644
--- a/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp
+++ b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp
@@ -49,7 +49,7 @@ using ClangBackEnd::UpdateProjectPartsMessage;
using ClangBackEnd::RemoveGeneratedFilesMessage;
using ClangBackEnd::RemoveProjectPartsMessage;
using ClangBackEnd::V2::FileContainer;
-using ClangBackEnd::V2::ProjectPartContainer;
+using ClangBackEnd::ProjectPartContainer;
using ClangBackEnd::PrecompiledHeadersUpdatedMessage;
using ::testing::Args;
@@ -97,13 +97,18 @@ TEST_F(PchManagerClientServerInProcess, SendAliveMessage)
TEST_F(PchManagerClientServerInProcess, SendUpdateProjectPartsMessage)
{
- ProjectPartContainer projectPart2{"projectPartId",
- {"-x", "c++-header", "-Wno-pragma-once-outside-header"},
- {{"DEFINE", "1", 1}},
- {"/includes"},
- {{1, 1}},
- {{1, 2}}};
- UpdateProjectPartsMessage message{{projectPart2}};
+ ProjectPartContainer projectPart2{
+ "projectPartId",
+ {"-x", "c++-header", "-Wno-pragma-once-outside-header"},
+ {{"DEFINE", "1", 1}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
+ {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {{1, 1}},
+ {{1, 2}},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All};
+ UpdateProjectPartsMessage message{{projectPart2}, {"-m32"}};
EXPECT_CALL(mockPchManagerServer, updateProjectParts(message));
diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp
index 77106268d1..9aab088b33 100644
--- a/tests/unit/unittest/pchmanagerserver-test.cpp
+++ b/tests/unit/unittest/pchmanagerserver-test.cpp
@@ -27,7 +27,7 @@
#include "mockclangpathwatcher.h"
#include "mockpchmanagerclient.h"
-#include "mockprojectpartqueue.h"
+#include "mockpchtaskgenerator.h"
#include "mockprojectparts.h"
#include "mockgeneratedfiles.h"
@@ -46,7 +46,7 @@ using Utils::PathString;
using Utils::SmallString;
using ClangBackEnd::V2::FileContainer;
using ClangBackEnd::V2::FileContainers;
-using ClangBackEnd::V2::ProjectPartContainer;
+using ClangBackEnd::ProjectPartContainer;
class PchManagerServer : public ::testing::Test
{
@@ -64,14 +64,15 @@ class PchManagerServer : public ::testing::Test
}
protected:
- NiceMock<MockProjectPartQueue> mockProjectPartQueue;
+ NiceMock<MockPchTaskGenerator> mockPchTaskGenerator;
NiceMock<MockClangPathWatcher> mockClangPathWatcher;
NiceMock<MockProjectParts> mockProjectParts;
NiceMock<MockGeneratedFiles> mockGeneratedFiles;
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
ClangBackEnd::FilePathCaching filePathCache{database};
- ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockProjectPartQueue, mockProjectParts, mockGeneratedFiles};
+ ClangBackEnd::PchManagerServer server{
+ mockClangPathWatcher, mockPchTaskGenerator, mockProjectParts, mockGeneratedFiles};
NiceMock<MockPchManagerClient> mockPchManagerClient;
SmallString projectPartId1 = "project1";
SmallString projectPartId2 = "project2";
@@ -80,22 +81,33 @@ protected:
PathString header1Path = TESTDATA_DIR "/BuildDependencyCollector_header1.h";
PathString header2Path = TESTDATA_DIR "/BuildDependencyCollector_header2.h";
ClangBackEnd::IdPaths idPath{projectPartId1, {1, 2}};
- ProjectPartContainer projectPart1{projectPartId1.clone(),
- {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
- {{"DEFINE", "1", 1}},
- {"/includes"},
- {id(header1Path)},
- {id(main1Path)}};
- ProjectPartContainer projectPart2{projectPartId2.clone(),
- {"-x", "c++-header", "-Wno-pragma-once-outside-header"},
- {{"DEFINE", "1", 1}},
- {"/includes"},
- {id(header2Path)},
- {id(main2Path)}};
+ ProjectPartContainer projectPart1{
+ projectPartId1.clone(),
+ {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
+ {{"DEFINE", "1", 1}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
+ {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {id(header1Path)},
+ {id(main1Path)},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All};
+ ProjectPartContainer projectPart2{
+ projectPartId2.clone(),
+ {"-x", "c++-header", "-Wno-pragma-once-outside-header"},
+ {{"DEFINE", "1", 1}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
+ {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {id(header2Path)},
+ {id(main2Path)},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All};
std::vector<ProjectPartContainer> projectParts{projectPart1, projectPart2};
std::vector<ProjectPartContainer> projectParts2{projectPart2};
FileContainer generatedFile{{"/path/to/", "file"}, "content", {}};
- ClangBackEnd::UpdateProjectPartsMessage updateProjectPartsMessage{Utils::clone(projectParts)};
+ ClangBackEnd::UpdateProjectPartsMessage updateProjectPartsMessage{
+ Utils::clone(projectParts), {"toolChainArgument"}};
ClangBackEnd::RemoveProjectPartsMessage removeProjectPartsMessage{{projectPart1.projectPartId.clone(),
projectPart2.projectPartId.clone()}};
};
@@ -104,8 +116,10 @@ TEST_F(PchManagerServer, FilterProjectPartsAndSendThemToQueue)
{
InSequence s;
- EXPECT_CALL(mockProjectParts, update(updateProjectPartsMessage.projectsParts)).WillOnce(Return(projectParts2));
- EXPECT_CALL(mockProjectPartQueue, addProjectParts(Eq(projectParts2)));
+ EXPECT_CALL(mockProjectParts, update(updateProjectPartsMessage.projectsParts))
+ .WillOnce(Return(projectParts2));
+ EXPECT_CALL(
+ mockPchTaskGenerator, addProjectParts(Eq(projectParts2), ElementsAre("toolChainArgument")));
server.updateProjectParts(updateProjectPartsMessage.clone());
}
@@ -146,14 +160,17 @@ TEST_F(PchManagerServer, SetPathWatcherNotifier)
{
EXPECT_CALL(mockClangPathWatcher, setNotifier(_));
- ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockProjectPartQueue, mockProjectParts, mockGeneratedFiles};
+ ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockPchTaskGenerator, mockProjectParts, mockGeneratedFiles};
}
TEST_F(PchManagerServer, UpdateProjectPartQueueByPathIds)
{
+ server.updateProjectParts(
+ ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
+
EXPECT_CALL(mockProjectParts, projects(ElementsAre(projectPart1.projectPartId)))
- .WillOnce(Return(std::vector<ClangBackEnd::V2::ProjectPartContainer>{{projectPart1}}));
- EXPECT_CALL(mockProjectPartQueue, addProjectParts(ElementsAre(projectPart1)));
+ .WillOnce(Return(std::vector<ClangBackEnd::ProjectPartContainer>{{projectPart1}}));
+ EXPECT_CALL(mockPchTaskGenerator, addProjectParts(ElementsAre(projectPart1), ElementsAre("toolChainArgument")));
server.pathsWithIdsChanged({projectPartId1});
}
@@ -166,4 +183,17 @@ TEST_F(PchManagerServer, SetProgress)
server.setProgress(20, 30);
}
+
+TEST_F(PchManagerServer, RemoveToolChainsArguments)
+{
+ server.updateProjectParts(
+ ClangBackEnd::UpdateProjectPartsMessage{{projectPart1}, {"toolChainArgument"}});
+
+ EXPECT_CALL(mockPchTaskGenerator, addProjectParts(_, _)).Times(0);
+ server.removeProjectParts(removeProjectPartsMessage.clone());
+
+ server.pathsWithIdsChanged({projectPart1.projectPartId});
+}
+
+
}
diff --git a/tests/unit/unittest/pchtaskgenerator-test.cpp b/tests/unit/unittest/pchtaskgenerator-test.cpp
index 0cb4c93583..74610f5170 100644
--- a/tests/unit/unittest/pchtaskgenerator-test.cpp
+++ b/tests/unit/unittest/pchtaskgenerator-test.cpp
@@ -32,10 +32,12 @@
namespace {
-using ClangBackEnd::BuildDependency;
using ClangBackEnd::BuildDependencies;
+using ClangBackEnd::BuildDependency;
using ClangBackEnd::CompilerMacro;
using ClangBackEnd::FilePathId;
+using ClangBackEnd::IncludeSearchPath;
+using ClangBackEnd::IncludeSearchPathType;
using ClangBackEnd::PchTask;
using ClangBackEnd::PchTaskSet;
using ClangBackEnd::SourceEntries;
@@ -49,21 +51,29 @@ protected:
NiceMock<MockBuildDependenciesProvider> mockBuildDependenciesProvider;
NiceMock<MockPchTasksMerger> mockPchTaskMerger;
ClangBackEnd::PchTaskGenerator generator{mockBuildDependenciesProvider, mockPchTaskMerger};
- ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1",
- {"--yi"},
- {{"YI", "1", 1},
- {"QI", "7", 1},
- {"ER", "2", 2},
- {"SAN", "3", 3},
- {"SE", "4", 4},
- {"BA", "8", 4},
- {"WU", "5", 5},
- {"LUI", "6", 6},
- {"JIU", "9", 9},
- {"SHI", "10", 10}},
- {"/yi"},
- {{1, 1}},
- {{1, 2}}};
+ ClangBackEnd::ProjectPartContainer projectPart1{
+ "ProjectPart1",
+ {"--yi"},
+ {{"YI", "1", 1},
+ {"QI", "7", 1},
+ {"ER", "2", 2},
+ {"SAN", "3", 3},
+ {"SE", "4", 4},
+ {"BA", "8", 4},
+ {"WU", "5", 5},
+ {"LUI", "6", 6},
+ {"JIU", "9", 9},
+ {"SHI", "10", 10}},
+ {IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
+ IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
+ IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System}},
+ {IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
+ IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User}},
+ {{1, 1}},
+ {{1, 2}},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::CXX11,
+ Utils::LanguageExtension::All};
SourceEntries firstSources{{1, SourceType::ProjectInclude, 1},
{2, SourceType::UserInclude, 1},
{3, SourceType::TopProjectInclude, 1},
@@ -73,32 +83,68 @@ protected:
BuildDependency buildDependency{firstSources, usedMacros, {}, {}, {}};
};
-TEST_F(PchTaskGenerator, Create)
+TEST_F(PchTaskGenerator, AddProjectParts)
+{
+ ON_CALL(mockBuildDependenciesProvider, create(_)).WillByDefault(Return(buildDependency));
+
+ EXPECT_CALL(
+ mockPchTaskMerger,
+ mergeTasks(
+ ElementsAre(AllOf(
+ Field(
+ &PchTaskSet::system,
+ AllOf(
+ Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")),
+ Field(&PchTask::includes, ElementsAre(5)),
+ Field(&PchTask::compilerMacros,
+ ElementsAre(CompilerMacro{"SE", "4", 4}, CompilerMacro{"WU", "5", 5})),
+ Field(&PchTask::usedMacros, ElementsAre(UsedMacro{"SE", 4}, UsedMacro{"WU", 5})),
+ Field(&PchTask::systemIncludeSearchPaths,
+ ElementsAre(
+ IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
+ IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
+ IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System})),
+ Field(&PchTask::projectIncludeSearchPaths,
+ ElementsAre(IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
+ IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User})),
+ Field(&PchTask::toolChainArguments, ElementsAre("--yi")),
+ Field(&PchTask::language, Eq(Utils::Language::Cxx)),
+ Field(&PchTask::languageVersion, Eq(Utils::LanguageVersion::CXX11)),
+ Field(&PchTask::languageExtension, Eq(Utils::LanguageExtension::All)))),
+ AllOf(Field(
+ &PchTaskSet::project,
+ AllOf(
+ Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")),
+ Field(&PchTask::includes, ElementsAre(3)),
+ Field(&PchTask::compilerMacros,
+ ElementsAre(CompilerMacro{"YI", "1", 1}, CompilerMacro{"SAN", "3", 3})),
+ Field(&PchTask::usedMacros, ElementsAre(UsedMacro{"YI", 1}, UsedMacro{"SAN", 3})),
+ Field(&PchTask::systemIncludeSearchPaths,
+ ElementsAre(
+ IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
+ IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
+ IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System})),
+ Field(&PchTask::projectIncludeSearchPaths,
+ ElementsAre(IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
+ IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User})),
+ Field(&PchTask::toolChainArguments, ElementsAre("--yi")),
+ Field(&PchTask::language, Eq(Utils::Language::Cxx)),
+ Field(&PchTask::languageVersion, Eq(Utils::LanguageVersion::CXX11)),
+ Field(&PchTask::languageExtension, Eq(Utils::LanguageExtension::All))))))),
+ ElementsAre(Eq("ToolChainArgument"))));
+
+ generator.addProjectParts({projectPart1}, {"ToolChainArgument"});
+}
+
+TEST_F(PchTaskGenerator, RemoveProjectParts)
{
ON_CALL(mockBuildDependenciesProvider, create(_)).WillByDefault(Return(buildDependency));
- EXPECT_CALL(mockPchTaskMerger,
- mergeTasks(ElementsAre(
- AllOf(Field(&PchTaskSet::system,
- AllOf(Field(&PchTask::projectPartIds, ElementsAre("ProjectPart1")),
- Field(&PchTask::includes, ElementsAre(4, 5)),
- Field(&PchTask::compilerMacros,
- ElementsAre(CompilerMacro{"SE", "4", 4},
- CompilerMacro{"WU", "5", 5})),
- Field(&PchTask::usedMacros,
- ElementsAre(UsedMacro{"SE", 4}, UsedMacro{"WU", 5})))),
- AllOf(Field(&PchTaskSet::project,
- AllOf(Field(&PchTask::projectPartIds,
- ElementsAre("ProjectPart1")),
- Field(&PchTask::includes, ElementsAre(1, 3)),
- Field(&PchTask::compilerMacros,
- ElementsAre(CompilerMacro{"YI", "1", 1},
- CompilerMacro{"SAN", "3", 3})),
- Field(&PchTask::usedMacros,
- ElementsAre(UsedMacro{"YI", 1},
- UsedMacro{"SAN", 3})))))))));
+ EXPECT_CALL(
+ mockPchTaskMerger,
+ removePchTasks(ElementsAre("project1", "project2")));
- generator.create({projectPart1});
+ generator.removeProjectParts({"project1", "project2"});
}
}
diff --git a/tests/unit/unittest/pchtaskqueue-test.cpp b/tests/unit/unittest/pchtaskqueue-test.cpp
index 2ee1bf3cad..aacd881553 100644
--- a/tests/unit/unittest/pchtaskqueue-test.cpp
+++ b/tests/unit/unittest/pchtaskqueue-test.cpp
@@ -35,6 +35,9 @@
namespace {
+using ClangBackEnd::IncludeSearchPath;
+using ClangBackEnd::IncludeSearchPaths;
+using ClangBackEnd::IncludeSearchPathType;
using ClangBackEnd::PchTask;
using ClangBackEnd::SlotUsage;
@@ -52,42 +55,75 @@ protected:
progressCounter,
mockPrecompiledHeaderStorage,
mockSqliteTransactionBackend};
+ IncludeSearchPaths systemIncludeSearchPaths{
+ {"/includes", 1, IncludeSearchPathType::BuiltIn},
+ {"/other/includes", 2, IncludeSearchPathType::System}};
+ IncludeSearchPaths projectIncludeSearchPaths{
+ {"/project/includes", 1, IncludeSearchPathType::User},
+ {"/other/project/includes", 2, IncludeSearchPathType::User}};
PchTask systemTask1{"ProjectPart1",
{1, 2},
{{"YI", "1", 1}, {"SAN", "3", 3}},
- {{"LIANG", 0}, {"YI", 1}}};
+ {{"LIANG", 0}, {"YI", 1}},
+ {"--yi"},
+ systemIncludeSearchPaths,
+ projectIncludeSearchPaths};
PchTask systemTask2{"ProjectPart2",
{1, 2},
{{"YI", "1", 1}, {"SAN", "3", 3}},
- {{"LIANG", 0}, {"YI", 1}}};
+ {{"LIANG", 0}, {"YI", 1}},
+ {"--yi"},
+ systemIncludeSearchPaths,
+ projectIncludeSearchPaths};
PchTask systemTask2b{"ProjectPart2",
{3, 4},
{{"YI", "1", 1}, {"SAN", "3", 3}},
- {{"LIANG", 0}, {"YI", 1}}};
+ {{"LIANG", 0}, {"YI", 1}},
+ {"--yi"},
+ systemIncludeSearchPaths,
+ projectIncludeSearchPaths};
PchTask systemTask3{"ProjectPart3",
{1, 2},
{{"YI", "1", 1}, {"SAN", "3", 3}},
- {{"LIANG", 0}, {"YI", 1}}};
+ {{"LIANG", 0}, {"YI", 1}},
+ {"--yi"},
+ systemIncludeSearchPaths,
+ projectIncludeSearchPaths};
PchTask projectTask1{"ProjectPart1",
{11, 12},
{{"SE", "4", 4}, {"WU", "5", 5}},
- {{"ER", 2}, {"SAN", 3}}};
+ {{"ER", 2}, {"SAN", 3}},
+ {"--yi"},
+ systemIncludeSearchPaths,
+ projectIncludeSearchPaths};
PchTask projectTask2{"ProjectPart2",
{11, 12},
{{"SE", "4", 4}, {"WU", "5", 5}},
- {{"ER", 2}, {"SAN", 3}}};
+ {{"ER", 2}, {"SAN", 3}},
+ {"--yi"},
+ systemIncludeSearchPaths,
+ projectIncludeSearchPaths};
PchTask projectTask2b{"ProjectPart2",
{21, 22},
{{"SE", "4", 4}, {"WU", "5", 5}},
- {{"ER", 2}, {"SAN", 3}}};
+ {{"ER", 2}, {"SAN", 3}},
+ {"--yi"},
+ systemIncludeSearchPaths,
+ projectIncludeSearchPaths};
PchTask projectTask3{"ProjectPart3",
{21, 22},
{{"SE", "4", 4}, {"WU", "5", 5}},
- {{"ER", 2}, {"SAN", 3}}};
+ {{"ER", 2}, {"SAN", 3}},
+ {"--yi"},
+ systemIncludeSearchPaths,
+ projectIncludeSearchPaths};
PchTask systemTask4{Utils::SmallStringVector{"ProjectPart1", "ProjectPart3"},
{1, 2},
{{"YI", "1", 1}, {"SAN", "3", 3}},
- {{"LIANG", 0}, {"YI", 1}}};
+ {{"LIANG", 0}, {"YI", 1}},
+ {"--yi"},
+ systemIncludeSearchPaths,
+ projectIncludeSearchPaths};
};
TEST_F(PchTaskQueue, AddProjectPchTask)
@@ -111,28 +147,31 @@ TEST_F(PchTaskQueue, AddSystemPchTask)
TEST_F(PchTaskQueue, AddProjectPchTasksCallsProcessEntriesForSystemTaskSchedulerIsNotBusy)
{
InSequence s;
+ queue.addProjectPchTasks({projectTask1, projectTask2});
EXPECT_CALL(mockSytemPchTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0}));
EXPECT_CALL(mockProjectPchTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0}));
EXPECT_CALL(mockProjectPchTaskScheduler, addTasks(SizeIs(2)));
- queue.addProjectPchTasks({projectTask1, projectTask2});
+ queue.processEntries();
}
TEST_F(PchTaskQueue, AddProjectPchTasksCallsProcessEntriesForSystemTaskSchedulerIsBusy)
{
InSequence s;
+ queue.addProjectPchTasks({projectTask1, projectTask2});
EXPECT_CALL(mockSytemPchTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 1}));
EXPECT_CALL(mockProjectPchTaskScheduler, slotUsage()).Times(0);
EXPECT_CALL(mockProjectPchTaskScheduler, addTasks(_)).Times(0);
- queue.addProjectPchTasks({projectTask1, projectTask2});
+ queue.processEntries();
}
TEST_F(PchTaskQueue, AddSystemPchTasksCallsProcessEntries)
{
InSequence s;
+ queue.addSystemPchTasks({projectTask1, projectTask2});
EXPECT_CALL(mockSytemPchTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0}));
EXPECT_CALL(mockSytemPchTaskScheduler, addTasks(SizeIs(2)));
@@ -140,7 +179,7 @@ TEST_F(PchTaskQueue, AddSystemPchTasksCallsProcessEntries)
EXPECT_CALL(mockProjectPchTaskScheduler, slotUsage()).Times(0);
EXPECT_CALL(mockProjectPchTaskScheduler, addTasks(_)).Times(0);
- queue.addSystemPchTasks({projectTask1, projectTask2});
+ queue.processEntries();
}
TEST_F(PchTaskQueue, AddProjectPchTasksCallsProgressCounter)
@@ -250,20 +289,13 @@ TEST_F(PchTaskQueue, CreateProjectTaskFromPchTask)
auto projectTask = projectTask1;
projectTask.systemPchPath = "/path/to/pch";
- EXPECT_CALL(mockSqliteTransactionBackend, lock());
- EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
+
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchSystemPrecompiledHeaderPath(Eq("ProjectPart1")))
- .WillOnce(Return(Utils::PathString{"/path/to/pch"}));
- EXPECT_CALL(mockSqliteTransactionBackend, commit());
- EXPECT_CALL(mockSqliteTransactionBackend, unlock());
+ .WillOnce(Return(ClangBackEnd::FilePath{"/path/to/pch"}));
EXPECT_CALL(mockPchCreator, generatePch(Eq(projectTask)));
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
- EXPECT_CALL(mockSqliteTransactionBackend, lock());
- EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockPrecompiledHeaderStorage,
insertProjectPrecompiledHeader(Eq("ProjectPart1"), Eq("/path/to/pch"), 99));
- EXPECT_CALL(mockSqliteTransactionBackend, commit());
- EXPECT_CALL(mockSqliteTransactionBackend, unlock());
tasks.front()(mockPchCreator);
}
@@ -277,19 +309,11 @@ TEST_F(PchTaskQueue, DeleteProjectPchEntryInDatabaseIfNoPchIsGenerated)
auto projectTask = projectTask1;
projectTask.systemPchPath = "/path/to/pch";
- EXPECT_CALL(mockSqliteTransactionBackend, lock());
- EXPECT_CALL(mockSqliteTransactionBackend, deferredBegin());
EXPECT_CALL(mockPrecompiledHeaderStorage, fetchSystemPrecompiledHeaderPath(Eq("ProjectPart1")))
- .WillOnce(Return(Utils::PathString{"/path/to/pch"}));
- EXPECT_CALL(mockSqliteTransactionBackend, commit());
- EXPECT_CALL(mockSqliteTransactionBackend, unlock());
+ .WillOnce(Return(ClangBackEnd::FilePath{"/path/to/pch"}));
EXPECT_CALL(mockPchCreator, generatePch(Eq(projectTask)));
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
- EXPECT_CALL(mockSqliteTransactionBackend, lock());
- EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockPrecompiledHeaderStorage, deleteProjectPrecompiledHeader(Eq("ProjectPart1")));
- EXPECT_CALL(mockSqliteTransactionBackend, commit());
- EXPECT_CALL(mockSqliteTransactionBackend, unlock());
tasks.front()(mockPchCreator);
}
@@ -310,14 +334,10 @@ TEST_F(PchTaskQueue, CreateSystemTaskFromPchTask)
EXPECT_CALL(mockPchCreator, generatePch(Eq(systemTask4)));
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
- EXPECT_CALL(mockSqliteTransactionBackend, lock());
- EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockPrecompiledHeaderStorage,
- insertSystemPrecompiledHeader(Eq("ProjectPart1"), Eq("/path/to/pch"), 99));
- EXPECT_CALL(mockPrecompiledHeaderStorage,
- insertSystemPrecompiledHeader(Eq("ProjectPart3"), Eq("/path/to/pch"), 99));
- EXPECT_CALL(mockSqliteTransactionBackend, commit());
- EXPECT_CALL(mockSqliteTransactionBackend, unlock());
+ insertSystemPrecompiledHeaders(UnorderedElementsAre("ProjectPart1", "ProjectPart3"),
+ Eq("/path/to/pch"),
+ 99));
tasks.front()(mockPchCreator);
}
@@ -331,12 +351,8 @@ TEST_F(PchTaskQueue, DeleteSystemPchEntryInDatabaseIfNoPchIsGenerated)
EXPECT_CALL(mockPchCreator, generatePch(Eq(systemTask4)));
EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
- EXPECT_CALL(mockSqliteTransactionBackend, lock());
- EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
- EXPECT_CALL(mockPrecompiledHeaderStorage, deleteSystemPrecompiledHeader(Eq("ProjectPart1")));
- EXPECT_CALL(mockPrecompiledHeaderStorage, deleteSystemPrecompiledHeader(Eq("ProjectPart3")));
- EXPECT_CALL(mockSqliteTransactionBackend, commit());
- EXPECT_CALL(mockSqliteTransactionBackend, unlock());
+ EXPECT_CALL(mockPrecompiledHeaderStorage,
+ deleteSystemPrecompiledHeaders(UnorderedElementsAre("ProjectPart1", "ProjectPart3")));
tasks.front()(mockPchCreator);
}
diff --git a/tests/unit/unittest/pchtasksmerger-test.cpp b/tests/unit/unittest/pchtasksmerger-test.cpp
index 8331e69009..6319389e73 100644
--- a/tests/unit/unittest/pchtasksmerger-test.cpp
+++ b/tests/unit/unittest/pchtasksmerger-test.cpp
@@ -29,16 +29,21 @@
#include <pchtasksmerger.h>
+namespace {
+
+using ClangBackEnd::IncludeSearchPath;
+using ClangBackEnd::IncludeSearchPathType;
using ClangBackEnd::PchTask;
using ClangBackEnd::PchTaskSet;
class PchTasksMerger : public testing::Test
{
protected:
- template<class T>
- T clone(T entry)
+ PchTask clone(PchTask entry) const
{
- return *&entry;
+ // entry.toolChainArguments = toolChainArguments;
+
+ return entry;
}
protected:
@@ -47,19 +52,44 @@ protected:
PchTask systemTask1{"ProjectPart1",
{1, 2},
{{"YI", "1", 1}, {"SAN", "3", 3}},
- {{"LIANG", 0}, {"YI", 1}}};
+ {{"LIANG", 0}, {"YI", 1}},
+ {"--yi"},
+ {IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
+ IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
+ IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System}},
+ {IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
+ IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User}}};
PchTask projectTask1{"ProjectPart1",
{11, 12},
{{"SE", "4", 4}, {"WU", "5", 5}},
- {{"ER", 2}, {"SAN", 3}}};
+ {{"ER", 2}, {"SAN", 3}},
+ {"--yi"},
+ {IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
+ IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
+ IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System}},
+ {IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
+ IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User}}};
PchTask systemTask2{"ProjectPart2",
{1, 2},
{{"YI", "1", 1}, {"SAN", "3", 3}},
- {{"LIANG", 0}, {"YI", 1}}};
+ {{"LIANG", 0}, {"YI", 1}},
+ {"--yi"},
+ {IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
+ IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
+ IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System}},
+ {IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
+ IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User}}};
PchTask projectTask2{"ProjectPart2",
{11, 12},
{{"SE", "4", 4}, {"WU", "5", 5}},
- {{"ER", 2}, {"SAN", 3}}};
+ {{"ER", 2}, {"SAN", 3}},
+ {"--yi"},
+ {IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
+ IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
+ IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System}},
+ {IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
+ IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User}}};
+ Utils::SmallStringVector toolChainArguments = {"toolChainArguments"};
};
TEST_F(PchTasksMerger, AddProjectTasks)
@@ -70,8 +100,8 @@ TEST_F(PchTasksMerger, AddProjectTasks)
EXPECT_CALL(mockPchTaskQueue, processEntries());
merger.mergeTasks(
- {{clone(systemTask1), clone(projectTask1)}, {clone(systemTask1), clone(projectTask2)}});
-
+ {{clone(systemTask1), clone(projectTask1)}, {clone(systemTask1), clone(projectTask2)}},
+ std::move(toolChainArguments));
}
TEST_F(PchTasksMerger, AddSystemTasks)
@@ -82,5 +112,14 @@ TEST_F(PchTasksMerger, AddSystemTasks)
EXPECT_CALL(mockPchTaskQueue, processEntries());
merger.mergeTasks(
- {{clone(systemTask1), clone(projectTask1)}, {clone(systemTask2), clone(projectTask2)}});
+ {{clone(systemTask1), clone(projectTask1)}, {clone(systemTask2), clone(projectTask2)}},
+ std::move(toolChainArguments));
+}
+
+TEST_F(PchTasksMerger, RemoveTasks)
+{
+ EXPECT_CALL(mockPchTaskQueue, removePchTasks(ElementsAre("project1", "project2")));
+
+ merger.removePchTasks({"project1", "project2"});
+}
}
diff --git a/tests/unit/unittest/precompiledheaderstorage-test.cpp b/tests/unit/unittest/precompiledheaderstorage-test.cpp
index 61fdfb5a88..fb65aa7c80 100644
--- a/tests/unit/unittest/precompiledheaderstorage-test.cpp
+++ b/tests/unit/unittest/precompiledheaderstorage-test.cpp
@@ -119,7 +119,7 @@ TEST_F(PrecompiledHeaderStorage, DeleteProjectPrecompiledHeaderStatementIsBusy)
storage.deleteProjectPrecompiledHeader("project1");
}
-TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeader)
+TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeaders)
{
InSequence s;
@@ -129,12 +129,17 @@ TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeader)
write(TypedEq<Utils::SmallStringView>("project1"),
TypedEq<Utils::SmallStringView>("/path/to/pch"),
TypedEq<long long>(22)));
+ EXPECT_CALL(insertProjectPartStatement, write(TypedEq<Utils::SmallStringView>("project2")));
+ EXPECT_CALL(insertSystemPrecompiledHeaderStatement,
+ write(TypedEq<Utils::SmallStringView>("project2"),
+ TypedEq<Utils::SmallStringView>("/path/to/pch"),
+ TypedEq<long long>(22)));
EXPECT_CALL(database, commit());
- storage.insertSystemPrecompiledHeader("project1", "/path/to/pch", 22);
+ storage.insertSystemPrecompiledHeaders({"project1", "project2"}, "/path/to/pch", 22);
}
-TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeaderStatementIsBusy)
+TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeadersStatementIsBusy)
{
InSequence s;
@@ -145,32 +150,43 @@ TEST_F(PrecompiledHeaderStorage, InsertSystemPrecompiledHeaderStatementIsBusy)
write(TypedEq<Utils::SmallStringView>("project1"),
TypedEq<Utils::SmallStringView>("/path/to/pch"),
TypedEq<long long>(22)));
+ EXPECT_CALL(insertProjectPartStatement, write(TypedEq<Utils::SmallStringView>("project2")));
+ EXPECT_CALL(insertSystemPrecompiledHeaderStatement,
+ write(TypedEq<Utils::SmallStringView>("project2"),
+ TypedEq<Utils::SmallStringView>("/path/to/pch"),
+ TypedEq<long long>(22)));
EXPECT_CALL(database, commit());
- storage.insertSystemPrecompiledHeader("project1", "/path/to/pch", 22);
+ storage.insertSystemPrecompiledHeaders({"project1", "project2"}, "/path/to/pch", 22);
}
-TEST_F(PrecompiledHeaderStorage, DeleteSystemPrecompiledHeader)
+TEST_F(PrecompiledHeaderStorage, DeleteSystemPrecompiledHeaders)
{
InSequence s;
EXPECT_CALL(database, immediateBegin());
- EXPECT_CALL(deleteSystemPrecompiledHeaderStatement, write(TypedEq<Utils::SmallStringView>("project1")));
+ EXPECT_CALL(deleteSystemPrecompiledHeaderStatement,
+ write(TypedEq<Utils::SmallStringView>("project1")));
+ EXPECT_CALL(deleteSystemPrecompiledHeaderStatement,
+ write(TypedEq<Utils::SmallStringView>("project2")));
EXPECT_CALL(database, commit());
- storage.deleteSystemPrecompiledHeader("project1");
+ storage.deleteSystemPrecompiledHeaders({"project1", "project2"});
}
-TEST_F(PrecompiledHeaderStorage, DeleteSystemPrecompiledHeaderStatementIsBusy)
+TEST_F(PrecompiledHeaderStorage, DeleteSystemPrecompiledHeadersStatementIsBusy)
{
InSequence s;
EXPECT_CALL(database, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy")));
EXPECT_CALL(database, immediateBegin());
- EXPECT_CALL(deleteSystemPrecompiledHeaderStatement, write(TypedEq<Utils::SmallStringView>("project1")));
+ EXPECT_CALL(deleteSystemPrecompiledHeaderStatement,
+ write(TypedEq<Utils::SmallStringView>("project1")));
+ EXPECT_CALL(deleteSystemPrecompiledHeaderStatement,
+ write(TypedEq<Utils::SmallStringView>("project2")));
EXPECT_CALL(database, commit());
- storage.deleteSystemPrecompiledHeader("project1");
+ storage.deleteSystemPrecompiledHeaders({"project1", "project2"});
}
TEST_F(PrecompiledHeaderStorage, CompilePrecompiledHeaderStatements)
@@ -187,7 +203,7 @@ TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderCalls)
EXPECT_CALL(database, deferredBegin());
EXPECT_CALL(fetchSystemPrecompiledHeaderPathStatement,
- valueReturnPathString(TypedEq<Utils::SmallStringView>("project1")));
+ valueReturnFilePath(TypedEq<Utils::SmallStringView>("project1")));
EXPECT_CALL(database, commit());
storage.fetchSystemPrecompiledHeaderPath("project1");
@@ -196,8 +212,8 @@ TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderCalls)
TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeader)
{
EXPECT_CALL(fetchSystemPrecompiledHeaderPathStatement,
- valueReturnPathString(TypedEq<Utils::SmallStringView>("project1")))
- .WillOnce(Return(Utils::PathString{"/path/to/pch"}));
+ valueReturnFilePath(TypedEq<Utils::SmallStringView>("project1")))
+ .WillOnce(Return(ClangBackEnd::FilePath{"/path/to/pch"}));
auto path = storage.fetchSystemPrecompiledHeaderPath("project1");
@@ -207,8 +223,8 @@ TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeader)
TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderReturnsEmptyPath)
{
EXPECT_CALL(fetchSystemPrecompiledHeaderPathStatement,
- valueReturnPathString(TypedEq<Utils::SmallStringView>("project1")))
- .WillOnce(Return(Utils::PathString{}));
+ valueReturnFilePath(TypedEq<Utils::SmallStringView>("project1")))
+ .WillOnce(Return(ClangBackEnd::FilePath{}));
auto path = storage.fetchSystemPrecompiledHeaderPath("project1");
@@ -218,8 +234,8 @@ TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderReturnsEmptyPath)
TEST_F(PrecompiledHeaderStorage, FetchSystemPrecompiledHeaderReturnsNullOptional)
{
EXPECT_CALL(fetchSystemPrecompiledHeaderPathStatement,
- valueReturnPathString(TypedEq<Utils::SmallStringView>("project1")))
- .WillOnce(Return(Utils::optional<Utils::PathString>{}));
+ valueReturnFilePath(TypedEq<Utils::SmallStringView>("project1")))
+ .WillOnce(Return(Utils::optional<ClangBackEnd::FilePath>{}));
auto path = storage.fetchSystemPrecompiledHeaderPath("project1");
diff --git a/tests/unit/unittest/progresscounter-test.cpp b/tests/unit/unittest/progresscounter-test.cpp
index 059bd3bae4..dde6419cc6 100644
--- a/tests/unit/unittest/progresscounter-test.cpp
+++ b/tests/unit/unittest/progresscounter-test.cpp
@@ -56,6 +56,15 @@ TEST_F(ProgressCounter, AddTotal)
counter.addTotal(7);
}
+TEST_F(ProgressCounter, AddTotalZero)
+{
+ counter.addTotal(5);
+
+ EXPECT_CALL(mockSetProgressCallback, Call(_, _)).Times(0);
+
+ counter.addTotal(0);
+}
+
TEST_F(ProgressCounter, RemoveTotal)
{
counter.addTotal(11);
@@ -66,6 +75,15 @@ TEST_F(ProgressCounter, RemoveTotal)
counter.removeTotal(7);
}
+TEST_F(ProgressCounter, RemoveTotalZero)
+{
+ counter.addTotal(11);
+
+ EXPECT_CALL(mockSetProgressCallback, Call(_, _)).Times(0);
+
+ counter.removeTotal(0);
+}
+
TEST_F(ProgressCounter, AddProgress)
{
counter.addTotal(11);
@@ -76,6 +94,16 @@ TEST_F(ProgressCounter, AddProgress)
counter.addProgress(4);
}
+TEST_F(ProgressCounter, AddProgressZero)
+{
+ counter.addTotal(11);
+ counter.addProgress(3);
+
+ EXPECT_CALL(mockSetProgressCallback, Call(_, _)).Times(0);
+
+ counter.addProgress(0);
+}
+
TEST_F(ProgressCounter, AddTotalAfterFinishingProgress)
{
counter.addTotal(11);
diff --git a/tests/unit/unittest/projectpartartefact-test.cpp b/tests/unit/unittest/projectpartartefact-test.cpp
index f7d3a031a4..b38f15333e 100644
--- a/tests/unit/unittest/projectpartartefact-test.cpp
+++ b/tests/unit/unittest/projectpartartefact-test.cpp
@@ -30,30 +30,32 @@
namespace {
using ClangBackEnd::CompilerMacro;
+using ClangBackEnd::IncludeSearchPath;
+using ClangBackEnd::IncludeSearchPathType;
TEST(ProjectPartArtefact, CompilerArguments)
{
- ClangBackEnd::ProjectPartArtefact artefact{"[\"-DFoo\",\"-DBar\"]", "", "", 1};
+ ClangBackEnd::ProjectPartArtefact artefact{"[\"-DFoo\",\"-DBar\"]", "", "", "", 1};
ASSERT_THAT(artefact.compilerArguments, ElementsAre(Eq("-DFoo"), Eq("-DBar")));
}
TEST(ProjectPartArtefact, EmptyCompilerArguments)
{
- ClangBackEnd::ProjectPartArtefact artefact{"", "", "", 1};
+ ClangBackEnd::ProjectPartArtefact artefact{"", "", "", "", 1};
ASSERT_THAT(artefact.compilerArguments, IsEmpty());
}
TEST(ProjectPartArtefact, CompilerArgumentsParseError)
{
- ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("\"-DFoo\",\"-DBar\"]", "", "", 1),
+ ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("\"-DFoo\",\"-DBar\"]", "", "", "", 1),
ClangBackEnd::ProjectPartArtefactParseError);
}
TEST(ProjectPartArtefact, CompilerMacros)
{
- ClangBackEnd::ProjectPartArtefact artefact{"", "{\"Foo\":\"1\",\"Bar\":\"42\"}", "", 1};
+ ClangBackEnd::ProjectPartArtefact artefact{"", R"([["Foo","1",1], ["Bar","42",2]])", "", "", 1};
ASSERT_THAT(artefact.compilerMacros,
UnorderedElementsAre(Eq(CompilerMacro{"Foo", "1", 1}), Eq(CompilerMacro{"Bar", "42", 2})));
@@ -61,35 +63,65 @@ TEST(ProjectPartArtefact, CompilerMacros)
TEST(ProjectPartArtefact, EmptyCompilerMacros)
{
- ClangBackEnd::ProjectPartArtefact artefact{"", "", "", 1};
+ ClangBackEnd::ProjectPartArtefact artefact{"", "", "", "", 1};
ASSERT_THAT(artefact.compilerMacros, IsEmpty());
}
TEST(ProjectPartArtefact, CompilerMacrosParseError)
{
- ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("", "\"Foo\":\"1\",\"Bar\":\"42\"}", "", 1),
+ ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("", R"([["Foo":"1", 1], ["Bar", "42", 2]])", "", "", 1),
ClangBackEnd::ProjectPartArtefactParseError);
}
-TEST(ProjectPartArtefact, IncludeSearchPaths)
+TEST(ProjectPartArtefact, SystemIncludeSearchPaths)
{
- ClangBackEnd::ProjectPartArtefact artefact{"", "", "[\"/includes\",\"/other/includes\"]", 1};
+ ClangBackEnd::ProjectPartArtefact artefact{
+ "", "", R"([["/includes", 1, 2], ["/other/includes", 2, 3]])", "", 1};
- ASSERT_THAT(artefact.includeSearchPaths, ElementsAre(Eq("/includes"), Eq("/other/includes")));
+ ASSERT_THAT(
+ artefact.systemIncludeSearchPaths,
+ ElementsAre(Eq(IncludeSearchPath("/includes", 1, IncludeSearchPathType::BuiltIn)),
+ Eq(IncludeSearchPath("/other/includes", 2, IncludeSearchPathType::System))));
}
-TEST(ProjectPartArtefact, EmptyIncludeSearchPaths)
+TEST(ProjectPartArtefact, EmptySystemIncludeSearchPaths)
{
- ClangBackEnd::ProjectPartArtefact artefact{"", "", "", 1};
+ ClangBackEnd::ProjectPartArtefact artefact{"", "", "", "", 1};
- ASSERT_THAT(artefact.includeSearchPaths, IsEmpty());
+ ASSERT_THAT(artefact.systemIncludeSearchPaths, IsEmpty());
}
-TEST(ProjectPartArtefact, IncludeSearchPathsParseError)
+TEST(ProjectPartArtefact, ProjectIncludeSearchPaths)
{
- ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("", "", "\"/includes\",\"/other/includes\"]", 1),
- ClangBackEnd::ProjectPartArtefactParseError);
+ ClangBackEnd::ProjectPartArtefact artefact{
+ "", "", R"([["/project/includes", 1, 1], ["/other/project/includes", 2, 1]])", "", 1};
+
+ ASSERT_THAT(
+ artefact.systemIncludeSearchPaths,
+ ElementsAre(
+ Eq(IncludeSearchPath("/project/includes", 1, IncludeSearchPathType::User)),
+ Eq(IncludeSearchPath("/other/project/includes", 2, IncludeSearchPathType::User))));
+}
+
+TEST(ProjectPartArtefact, EmptyProjectIncludeSearchPaths)
+{
+ ClangBackEnd::ProjectPartArtefact artefact{"", "", "", "", 1};
+
+ ASSERT_THAT(artefact.projectIncludeSearchPaths, IsEmpty());
}
+TEST(ProjectPartArtefact, IncludeSystemSearchPathsParseError)
+{
+ ASSERT_THROW(
+ ClangBackEnd::ProjectPartArtefact("", "", R"(["/includes", 1, 3], ["/other/includes", 2, 2]])", "", 1),
+ ClangBackEnd::ProjectPartArtefactParseError);
+}
+
+TEST(ProjectPartArtefact, IncludeProjectSearchPathsParseError)
+{
+ ASSERT_THROW(
+ ClangBackEnd::ProjectPartArtefact("", "", R"(["/project/includes", 1, 1], ["/other/project/includes", 2, 1]])", "", 1),
+ ClangBackEnd::ProjectPartArtefactParseError);
+}
}
diff --git a/tests/unit/unittest/projectpartqueue-test.cpp b/tests/unit/unittest/projectpartqueue-test.cpp
deleted file mode 100644
index 65318a3e91..0000000000
--- a/tests/unit/unittest/projectpartqueue-test.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2018 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "googletest.h"
-
-#include "mocktaskscheduler.h"
-#include "mockpchcreator.h"
-#include "mockprecompiledheaderstorage.h"
-#include "mocksqlitetransactionbackend.h"
-
-#include <projectpartqueue.h>
-#include <progresscounter.h>
-
-namespace {
-
-using ClangBackEnd::SlotUsage;
-using ClangBackEnd::V2::ProjectPartContainer;
-
-class ProjectPartQueue : public testing::Test
-{
-protected:
- NiceMock<MockTaskScheduler<ClangBackEnd::ProjectPartQueue::Task>> mockTaskScheduler;
- MockPrecompiledHeaderStorage mockPrecompiledHeaderStorage;
- MockSqliteTransactionBackend mockSqliteTransactionBackend;
- NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
- ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()};
- ClangBackEnd::ProjectPartQueue queue{mockTaskScheduler, mockPrecompiledHeaderStorage, mockSqliteTransactionBackend, progressCounter};
- ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1",
- {"--yi"},
- {{"YI","1", 1}},
- {"/yi"},
- {1},
- {2}};
- ClangBackEnd::V2::ProjectPartContainer projectPart2{"ProjectPart2",
- {"--er"},
- {{"ER","2", 1}},
- {"/bar"},
- {1},
- {2}};
- ClangBackEnd::V2::ProjectPartContainer projectPart2b{"ProjectPart2",
- {"--liang"},
- {{"LIANG","3", 1}},
- {"/liang"},
- {3},
- {2, 4}};
- ClangBackEnd::V2::ProjectPartContainer projectPart3{"ProjectPart3",
- {"--san"},
- {{"SAN","2", 1}},
- {"/SAN"},
- {1},
- {2}};
-};
-
-TEST_F(ProjectPartQueue, AddProjectPart)
-{
- queue.addProjectParts({projectPart1});
-
- queue.addProjectParts({projectPart2});
-
- ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2));
-}
-
-TEST_F(ProjectPartQueue, AddProjectPartCallsProcessEntries)
-{
- InSequence s;
-
- EXPECT_CALL(mockTaskScheduler, slotUsage()).WillRepeatedly(Return(SlotUsage{2, 0}));
- EXPECT_CALL(mockTaskScheduler, addTasks(SizeIs(2)));
-
- queue.addProjectParts({projectPart1, projectPart2});
-}
-
-TEST_F(ProjectPartQueue, AddProjectPartCallsProgressCounter)
-{
- queue.addProjectParts({projectPart1, projectPart2});
-
- EXPECT_CALL(mockSetProgressCallback, Call(0, 3));
-
- queue.addProjectParts({projectPart2b, projectPart3});
-}
-
-TEST_F(ProjectPartQueue, IgnoreIdenticalProjectPart)
-{
- queue.addProjectParts({projectPart1, projectPart2});
-
- queue.addProjectParts({projectPart1, projectPart2});
-
- ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2));
-}
-
-TEST_F(ProjectPartQueue, ReplaceProjectPartWithSameId)
-{
- queue.addProjectParts({projectPart1, projectPart2});
-
- queue.addProjectParts({projectPart1, projectPart2b, projectPart3});
-
- ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart2b, projectPart3));
-}
-
-TEST_F(ProjectPartQueue, RemoveProjectPart)
-{
- queue.addProjectParts({projectPart1, projectPart2, projectPart3});
-
- queue.removeProjectParts({projectPart2.projectPartId});
-
- ASSERT_THAT(queue.projectParts(), ElementsAre(projectPart1, projectPart3));
-}
-
-TEST_F(ProjectPartQueue, RemoveProjectPartCallsProgressCounter)
-{
- queue.addProjectParts({projectPart1, projectPart2, projectPart3});
-
- EXPECT_CALL(mockSetProgressCallback, Call(0, 2));
-
- queue.removeProjectParts({projectPart2.projectPartId});
-}
-
-TEST_F(ProjectPartQueue, CreateTasksSizeEqualsInputSize)
-{
- auto tasks = queue.createPchTasks({projectPart1, projectPart2});
-
- ASSERT_THAT(tasks, SizeIs(2));
-}
-
-TEST_F(ProjectPartQueue, CreateTaskFromProjectPart)
-{
- InSequence s;
- MockPchCreator mockPchCreator;
- ClangBackEnd::ProjectPartPch projectPartPch{"project1", "/path/to/pch", 99};
- auto tasks = queue.createPchTasks({projectPart1});
-
- EXPECT_CALL(mockPchCreator, generatePchDeprecated(Eq(projectPart1)));
- EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
- EXPECT_CALL(mockSqliteTransactionBackend, lock());
- EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
- EXPECT_CALL(mockPrecompiledHeaderStorage, insertProjectPrecompiledHeader(Eq("project1"), Eq("/path/to/pch"), 99));
- EXPECT_CALL(mockSqliteTransactionBackend, commit());
- EXPECT_CALL(mockSqliteTransactionBackend, unlock());
-
- tasks.front()(mockPchCreator);
-}
-
-TEST_F(ProjectPartQueue, DeletePchEntryInDatabaseIfNoPchIsGenerated)
-{
- InSequence s;
- MockPchCreator mockPchCreator;
- ClangBackEnd::ProjectPartPch projectPartPch{"project1", "", 0};
- auto tasks = queue.createPchTasks({projectPart1});
-
- EXPECT_CALL(mockPchCreator, generatePchDeprecated(Eq(projectPart1)));
- EXPECT_CALL(mockPchCreator, projectPartPch()).WillOnce(ReturnRef(projectPartPch));
- EXPECT_CALL(mockSqliteTransactionBackend, lock());
- EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
- EXPECT_CALL(mockPrecompiledHeaderStorage, deleteProjectPrecompiledHeader(Eq("project1")));
- EXPECT_CALL(mockSqliteTransactionBackend, commit());
- EXPECT_CALL(mockSqliteTransactionBackend, unlock());
-
- tasks.front()(mockPchCreator);
-}
-
-}
diff --git a/tests/unit/unittest/projectparts-test.cpp b/tests/unit/unittest/projectparts-test.cpp
index 123a43d28f..87ab509206 100644
--- a/tests/unit/unittest/projectparts-test.cpp
+++ b/tests/unit/unittest/projectparts-test.cpp
@@ -27,7 +27,7 @@
#include <projectparts.h>
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
namespace {
@@ -35,7 +35,7 @@ using testing::ElementsAre;
using testing::UnorderedElementsAre;
using testing::IsEmpty;
-using ClangBackEnd::V2::ProjectPartContainer;
+using ClangBackEnd::ProjectPartContainer;
using ClangBackEnd::FilePathId;
class ProjectParts : public testing::Test
@@ -47,24 +47,39 @@ protected:
FilePathId firstSource{11};
FilePathId secondSource{12};
FilePathId thirdSource{13};
- ProjectPartContainer projectPartContainer1{"id",
- {"-DUNIX", "-O2"},
- {{"DEFINE", "1", 1}},
- {"/includes"},
- {firstHeader, secondHeader},
- {firstSource, secondSource}};
- ProjectPartContainer updatedProjectPartContainer1{"id",
- {"-DUNIX", "-O2"},
- {{"DEFINE", "1", 1}},
- {"/includes"},
- {firstHeader, secondHeader},
- {firstSource, secondSource, thirdSource}};
- ProjectPartContainer projectPartContainer2{"id2",
- {"-DUNIX", "-O2"},
- {{"DEFINE", "1", 1}},
- {"/includes"},
- {firstHeader, secondHeader},
- {firstSource, secondSource}};
+ ProjectPartContainer projectPartContainer1{
+ "id",
+ {"-DUNIX", "-O2"},
+ {{"DEFINE", "1", 1}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
+ {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {firstHeader, secondHeader},
+ {firstSource, secondSource},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All};
+ ProjectPartContainer updatedProjectPartContainer1{
+ "id",
+ {"-DUNIX", "-O2"},
+ {{"DEFINE", "1", 1}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
+ {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {firstHeader, secondHeader},
+ {firstSource, secondSource, thirdSource},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All};
+ ProjectPartContainer projectPartContainer2{
+ "id2",
+ {"-DUNIX", "-O2"},
+ {{"DEFINE", "1", 1}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
+ {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User}},
+ {firstHeader, secondHeader},
+ {firstSource, secondSource},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All};
};
TEST_F(ProjectParts, GetNoProjectPartsForAddingEmptyProjectParts)
diff --git a/tests/unit/unittest/projectupdater-test.cpp b/tests/unit/unittest/projectupdater-test.cpp
index 88f438b82c..293a4ef15e 100644
--- a/tests/unit/unittest/projectupdater-test.cpp
+++ b/tests/unit/unittest/projectupdater-test.cpp
@@ -43,6 +43,7 @@
#include <updategeneratedfilesmessage.h>
#include <updateprojectpartsmessage.h>
+#include <projectexplorer/projectexplorerconstants.h>
#include <cpptools/compileroptionsbuilder.h>
#include <cpptools/projectpart.h>
@@ -57,8 +58,10 @@ using testing::NiceMock;
using testing::AnyNumber;
using ClangBackEnd::CompilerMacro;
+using ClangBackEnd::IncludeSearchPath;
+using ClangBackEnd::IncludeSearchPathType;
using ClangBackEnd::V2::FileContainer;
-using ClangBackEnd::V2::ProjectPartContainer;
+using ClangBackEnd::ProjectPartContainer;
using CppTools::CompilerOptionsBuilder;
using ProjectExplorer::HeaderPath;
@@ -96,23 +99,31 @@ protected:
projectPartId2 = projectPart2.id();
- Utils::SmallStringVector arguments{ClangPchManager::ProjectUpdater::compilerArguments(
+ Utils::SmallStringVector arguments{ClangPchManager::ProjectUpdater::toolChainArguments(
&projectPart)};
- Utils::SmallStringVector arguments2{ClangPchManager::ProjectUpdater::compilerArguments(
+ Utils::SmallStringVector arguments2{ClangPchManager::ProjectUpdater::toolChainArguments(
&projectPart2)};
expectedContainer = {projectPartId.clone(),
arguments.clone(),
Utils::clone(compilerMacros),
+ {{CLANG_RESOURCE_DIR, 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
{},
{filePathId(headerPaths[1])},
- {filePathIds(sourcePaths)}};
+ {filePathIds(sourcePaths)},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::LatestCxx,
+ Utils::LanguageExtension::None};
expectedContainer2 = {projectPartId2.clone(),
arguments2.clone(),
Utils::clone(compilerMacros),
+ {{CLANG_RESOURCE_DIR, 1, ClangBackEnd::IncludeSearchPathType::BuiltIn}},
{},
{filePathId(headerPaths[1])},
- {filePathIds(sourcePaths)}};
+ {filePathIds(sourcePaths)},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::LatestCxx,
+ Utils::LanguageExtension::None};
}
protected:
@@ -145,12 +156,13 @@ protected:
TEST_F(ProjectUpdater, CallUpdateProjectParts)
{
std::vector<CppTools::ProjectPart*> projectParts = {&projectPart2, &projectPart};
- ClangBackEnd::UpdateProjectPartsMessage message{{expectedContainer.clone(), expectedContainer2.clone()}};
+ ClangBackEnd::UpdateProjectPartsMessage message{
+ {expectedContainer.clone(), expectedContainer2.clone()}, {"toolChainArgument"}};
updater.updateGeneratedFiles({generatedFile});
EXPECT_CALL(mockPchManagerServer, updateProjectParts(message));
- updater.updateProjectParts(projectParts);
+ updater.updateProjectParts(projectParts, {"toolChainArgument"});
}
TEST_F(ProjectUpdater, CallUpdateGeneratedFilesWithSortedEntries)
@@ -253,14 +265,109 @@ TEST_F(ProjectUpdater, CreateSortedCompilerMacros)
TEST_F(ProjectUpdater, CreateSortedIncludeSearchPaths)
{
+ CppTools::ProjectPart projectPart;
ProjectExplorer::HeaderPath includePath{"/to/path1", ProjectExplorer::HeaderPathType::User};
ProjectExplorer::HeaderPath includePath2{"/to/path2", ProjectExplorer::HeaderPathType::User};
ProjectExplorer::HeaderPath invalidPath;
- ProjectExplorer::HeaderPath frameworkPath{"/framework/path", ProjectExplorer::HeaderPathType::Framework};
+ ProjectExplorer::HeaderPath frameworkPath{"/framework/path",
+ ProjectExplorer::HeaderPathType::Framework};
+ ProjectExplorer::HeaderPath builtInPath{"/builtin/path", ProjectExplorer::HeaderPathType::BuiltIn};
+ ProjectExplorer::HeaderPath systemPath{"/system/path", ProjectExplorer::HeaderPathType::System};
+ projectPart.headerPaths = {
+ systemPath, builtInPath, frameworkPath, includePath2, includePath, invalidPath};
+
+ auto paths = updater.createIncludeSearchPaths(projectPart);
+
+ ASSERT_THAT(paths.system,
+ ElementsAre(Eq(IncludeSearchPath{systemPath.path, 1, IncludeSearchPathType::System}),
+ Eq(IncludeSearchPath{builtInPath.path, 4, IncludeSearchPathType::BuiltIn}),
+ Eq(IncludeSearchPath{frameworkPath.path, 2, IncludeSearchPathType::Framework}),
+ Eq(IncludeSearchPath{CLANG_RESOURCE_DIR,
+ 3,
+ ClangBackEnd::IncludeSearchPathType::BuiltIn})));
+ ASSERT_THAT(paths.project,
+ ElementsAre(Eq(IncludeSearchPath{includePath.path, 2, IncludeSearchPathType::User}),
+ Eq(IncludeSearchPath{includePath2.path, 1, IncludeSearchPathType::User})));
+}
+
+TEST_F(ProjectUpdater, ToolChainArguments)
+{
+ projectPart.toolChainTargetTriple = "target";
+ projectPart.extraCodeModelFlags.push_back("extraflags");
+ projectPart.compilerFlags.push_back("-fPIC");
+ projectPart.projectConfigFile = "config.h";
- auto paths = updater.createIncludeSearchPaths({frameworkPath, includePath2, includePath, invalidPath});
+ auto arguments = updater.toolChainArguments(&projectPart);
- ASSERT_THAT(paths, ElementsAre(includePath.path, includePath2.path, frameworkPath.path));
+ ASSERT_THAT(arguments,
+ ElementsAre("-m32", "-fPIC", "--target=target", "extraflags", "-include", "config.h"));
+}
+
+TEST_F(ProjectUpdater, ToolChainArgumentsMSVC)
+{
+ projectPart.toolChainTargetTriple = "target";
+ projectPart.extraCodeModelFlags.push_back("extraflags");
+ projectPart.toolchainType = ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID;
+ projectPart.isMsvc2015Toolchain = true;
+
+ auto arguments = updater.toolChainArguments(&projectPart);
+
+ ASSERT_THAT(arguments,
+ ElementsAre("-m32",
+ "--target=target",
+ "extraflags",
+ "-U__clang__",
+ "-U__clang_major__",
+ "-U__clang_minor__",
+ "-U__clang_patchlevel__",
+ "-U__clang_version__",
+ "-U__cpp_aggregate_bases",
+ "-U__cpp_aggregate_nsdmi",
+ "-U__cpp_alias_templates",
+ "-U__cpp_aligned_new",
+ "-U__cpp_attributes",
+ "-U__cpp_binary_literals",
+ "-U__cpp_capture_star_this",
+ "-U__cpp_constexpr",
+ "-U__cpp_decltype",
+ "-U__cpp_decltype_auto",
+ "-U__cpp_deduction_guides",
+ "-U__cpp_delegating_constructors",
+ "-U__cpp_digit_separators",
+ "-U__cpp_enumerator_attributes",
+ "-U__cpp_exceptions",
+ "-U__cpp_fold_expressions",
+ "-U__cpp_generic_lambdas",
+ "-U__cpp_guaranteed_copy_elision",
+ "-U__cpp_hex_float",
+ "-U__cpp_if_constexpr",
+ "-U__cpp_inheriting_constructors",
+ "-U__cpp_init_captures",
+ "-U__cpp_initializer_lists",
+ "-U__cpp_inline_variables",
+ "-U__cpp_lambdas",
+ "-U__cpp_namespace_attributes",
+ "-U__cpp_nested_namespace_definitions",
+ "-U__cpp_noexcept_function_type",
+ "-U__cpp_nontype_template_args",
+ "-U__cpp_nontype_template_parameter_auto",
+ "-U__cpp_nsdmi",
+ "-U__cpp_range_based_for",
+ "-U__cpp_raw_strings",
+ "-U__cpp_ref_qualifiers",
+ "-U__cpp_return_type_deduction",
+ "-U__cpp_rtti",
+ "-U__cpp_rvalue_references",
+ "-U__cpp_static_assert",
+ "-U__cpp_structured_bindings",
+ "-U__cpp_template_auto",
+ "-U__cpp_threadsafe_static_init",
+ "-U__cpp_unicode_characters",
+ "-U__cpp_unicode_literals",
+ "-U__cpp_user_defined_literals",
+ "-U__cpp_variable_templates",
+ "-U__cpp_variadic_templates",
+ "-U__cpp_variadic_using"));
}
}
diff --git a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
index 55af349bbb..659dcf735f 100644
--- a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
+++ b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp
@@ -52,7 +52,7 @@ using ClangBackEnd::RemoveProjectPartsMessage;
using ClangBackEnd::UpdateProjectPartsMessage;
using ClangBackEnd::UpdateGeneratedFilesMessage;
using ClangBackEnd::V2::FileContainer;
-using ClangBackEnd::V2::ProjectPartContainer;
+using ClangBackEnd::ProjectPartContainer;
class RefactoringClientServerInProcess : public ::testing::Test
{
@@ -192,10 +192,17 @@ TEST_F(RefactoringClientServerInProcess, SendUpdateProjectPartsMessage)
ProjectPartContainer projectPart2{"projectPartId",
{"-x", "c++-header", "-Wno-pragma-once-outside-header"},
{{"DEFINE", "1", 1}},
- {"/includes"},
+ {IncludeSearchPath{"/system/path", 2, IncludeSearchPathType::System},
+ IncludeSearchPath{"/builtin/path", 3, IncludeSearchPathType::BuiltIn},
+ IncludeSearchPath{"/framework/path", 1, IncludeSearchPathType::System}},
+ {IncludeSearchPath{"/to/path1", 1, IncludeSearchPathType::User},
+ IncludeSearchPath{"/to/path2", 2, IncludeSearchPathType::User}},
{{1, 1}},
- {{1, 2}}};
- UpdateProjectPartsMessage message{{projectPart2}};
+ {{1, 2}},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All};
+ UpdateProjectPartsMessage message{{projectPart2}, {"toolChainArgument"}};
EXPECT_CALL(mockRefactoringServer, updateProjectParts(message));
diff --git a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
index 555d742a60..cfae1d80f0 100644
--- a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
+++ b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp
@@ -88,7 +88,7 @@ TEST_F(RefactoringDatabaseInitializer, AddProjectPartsTable)
{
InSequence s;
- EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectParts(projectPartId INTEGER PRIMARY KEY, projectPartName TEXT, compilerArguments TEXT, compilerMacros TEXT, includeSearchPaths TEXT)")));
+ EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectParts(projectPartId INTEGER PRIMARY KEY, projectPartName TEXT, compilerArguments TEXT, compilerMacros TEXT, systemIncludeSearchPaths TEXT, projectIncludeSearchPaths TEXT)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectParts_projectPartName ON projectParts(projectPartName)")));
initializer.createProjectPartsTable();
@@ -160,7 +160,7 @@ TEST_F(RefactoringDatabaseInitializer, CreateInTheContructor)
EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_sources_directoryId_sourceName ON sources(directoryId, sourceName)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS directories(directoryId INTEGER PRIMARY KEY, directoryPath TEXT)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_directories_directoryPath ON directories(directoryPath)")));
- EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectParts(projectPartId INTEGER PRIMARY KEY, projectPartName TEXT, compilerArguments TEXT, compilerMacros TEXT, includeSearchPaths TEXT)")));
+ EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectParts(projectPartId INTEGER PRIMARY KEY, projectPartName TEXT, compilerArguments TEXT, compilerMacros TEXT, systemIncludeSearchPaths TEXT, projectIncludeSearchPaths TEXT)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectParts_projectPartName ON projectParts(projectPartName)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectPartsSources(projectPartId INTEGER, sourceId INTEGER, sourceType INTEGER)")));
EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectPartsSources_sourceId_projectPartId ON projectPartsSources(sourceId, projectPartId)")));
diff --git a/tests/unit/unittest/refactoringprojectupdater-test.cpp b/tests/unit/unittest/refactoringprojectupdater-test.cpp
index 9c878697a4..ceb6d4b15b 100644
--- a/tests/unit/unittest/refactoringprojectupdater-test.cpp
+++ b/tests/unit/unittest/refactoringprojectupdater-test.cpp
@@ -52,7 +52,7 @@ MATCHER_P(IsProjectPartContainer, projectPartId,
std::string(negation ? "hasn't" : "has")
+ " name " + std::string(projectPartId))
{
- const ClangBackEnd::V2::ProjectPartContainer &container = arg;
+ const ClangBackEnd::ProjectPartContainer &container = arg;
return container.projectPartId == projectPartId;
}
diff --git a/tests/unit/unittest/refactoringserver-test.cpp b/tests/unit/unittest/refactoringserver-test.cpp
index 42fff8dfd5..b8b97437e4 100644
--- a/tests/unit/unittest/refactoringserver-test.cpp
+++ b/tests/unit/unittest/refactoringserver-test.cpp
@@ -54,18 +54,20 @@ using testing::Property;
using testing::_;
using ClangBackEnd::FilePath;
+using ClangBackEnd::IncludeSearchPaths;
+using ClangBackEnd::IncludeSearchPathType;
using ClangBackEnd::RequestSourceLocationsForRenamingMessage;
using ClangBackEnd::RequestSourceRangesAndDiagnosticsForQueryMessage;
using ClangBackEnd::RequestSourceRangesForQueryMessage;
using ClangBackEnd::SourceLocationsContainer;
using ClangBackEnd::SourceLocationsForRenamingMessage;
using ClangBackEnd::SourceRangesAndDiagnosticsForQueryMessage;
-using ClangBackEnd::SourceRangesForQueryMessage;
using ClangBackEnd::SourceRangesContainer;
+using ClangBackEnd::SourceRangesForQueryMessage;
using ClangBackEnd::V2::FileContainer;
using ClangBackEnd::V2::FileContainers;
-using ClangBackEnd::V2::ProjectPartContainer;
-using ClangBackEnd::V2::ProjectPartContainers;
+using ClangBackEnd::ProjectPartContainer;
+using ClangBackEnd::ProjectPartContainers;
MATCHER_P2(IsSourceLocation, line, column,
std::string(negation ? "isn't " : "is ")
@@ -325,18 +327,24 @@ TEST_F(RefactoringServer, RemoveGeneratedFilesSetMemberWhichIsUsedForSymbolIndex
TEST_F(RefactoringServer, UpdateProjectPartsCallsSymbolIndexingUpdateProjectParts)
{
- ProjectPartContainers projectParts{{{"projectPartId",
- {"-I", TESTDATA_DIR},
- {{"DEFINE", "1", 1}},
- {"/includes"},
- {filePathId("header1.h")},
- {filePathId("main.cpp")}}}};
-
+ ProjectPartContainers projectParts{
+ {{"projectPartId",
+ {"-I", TESTDATA_DIR},
+ {{"DEFINE", "1", 1}},
+ IncludeSearchPaths{{"/includes", 1, IncludeSearchPathType::BuiltIn},
+ {"/other/includes", 2, IncludeSearchPathType::System}},
+ IncludeSearchPaths{{"/project/includes", 1, IncludeSearchPathType::User},
+ {"/other/project/includes", 2, IncludeSearchPathType::User}},
+ {filePathId("header1.h")},
+ {filePathId("main.cpp")},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All}}};
EXPECT_CALL(mockSymbolIndexing,
updateProjectParts(projectParts));
- refactoringServer.updateProjectParts({Utils::clone(projectParts)});
+ refactoringServer.updateProjectParts({Utils::clone(projectParts), {}});
}
TEST_F(RefactoringServer, SetProgress)
diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp
index 37dc4071a0..a5ee83b2b8 100644
--- a/tests/unit/unittest/symbolindexer-test.cpp
+++ b/tests/unit/unittest/symbolindexer-test.cpp
@@ -33,7 +33,7 @@
#include <filepathcaching.h>
#include <filestatuscache.h>
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
#include <refactoringdatabaseinitializer.h>
#include <processormanager.h>
#include <symbolindexer.h>
@@ -54,8 +54,8 @@ using ClangBackEnd::FileStatuses;
using ClangBackEnd::FilePathId;
using ClangBackEnd::FilePathIds;
using ClangBackEnd::FilePathView;
-using ClangBackEnd::V2::ProjectPartContainer;
-using ClangBackEnd::V2::ProjectPartContainers;
+using ClangBackEnd::ProjectPartContainer;
+using ClangBackEnd::ProjectPartContainers;
using ClangBackEnd::V2::FileContainers;
using ClangBackEnd::SymbolEntries;
using ClangBackEnd::SymbolEntry;
@@ -164,24 +164,43 @@ protected:
ClangBackEnd::FilePathId header1PathId{filePathId(TESTDATA_DIR "/symbolindexer_header2.h")};
PathString generatedFileName = "BuildDependencyCollector_generated_file.h";
ClangBackEnd::FilePathId generatedFilePathId21;
+ ClangBackEnd::IncludeSearchPaths systemIncludeSearchPaths{
+ {"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn},
+ {TESTDATA_DIR, 2, ClangBackEnd::IncludeSearchPathType::System},
+ {"/other/includes", 3, ClangBackEnd::IncludeSearchPathType::System}};
+ ClangBackEnd::IncludeSearchPaths projectIncludeSearchPaths{
+ {"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User},
+ {"/other/project/includes", 2, ClangBackEnd::IncludeSearchPathType::User}};
ProjectPartContainer projectPart1{"project1",
- {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
+ {"-Wno-pragma-once-outside-header"},
{{"BAR", "1", 1}, {"FOO", "1", 2}},
- {"/includes"},
+ Utils::clone(systemIncludeSearchPaths),
+ Utils::clone(projectIncludeSearchPaths),
{header1PathId},
- {main1PathId}};
+ {main1PathId},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::CXX14,
+ Utils::LanguageExtension::None};
ProjectPartContainer projectPart2{"project2",
- {"-I", TESTDATA_DIR, "-x", "c++-header", "-Wno-pragma-once-outside-header"},
+ {"-Wno-pragma-once-outside-header"},
{{"BAR", "1", 1}, {"FOO", "0", 2}},
- {"/includes"},
+ Utils::clone(systemIncludeSearchPaths),
+ Utils::clone(projectIncludeSearchPaths),
{header2PathId},
- {main2PathId}};
+ {main2PathId},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::CXX14,
+ Utils::LanguageExtension::None};
ProjectPartContainer projectPart3{"project3",
- {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
+ {"-Wno-pragma-once-outside-header"},
{{"BAR", "1", 1}, {"FOO", "1", 2}},
- {"/includes", "/other/includes"},
+ Utils::clone(systemIncludeSearchPaths),
+ Utils::clone(projectIncludeSearchPaths),
{header1PathId},
- {main1PathId}};
+ {main1PathId},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::CXX14,
+ Utils::LanguageExtension::None};
FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"},
"void f();",
{}}};
@@ -191,8 +210,16 @@ protected:
UsedMacros usedMacros{{"Foo", 1}};
FileStatuses fileStatus{{2, 3, 4, false}};
SourceDependencies sourceDependencies{{1, 2}, {1, 3}};
- ClangBackEnd::ProjectPartArtefact artefact{"[\"-DFOO\"]", "{\"FOO\":\"1\",\"BAR\":\"1\"}", "[\"/includes\"]", 74};
- ClangBackEnd::ProjectPartArtefact emptyArtefact{"", "", "", 74};
+ Utils::SmallString systemIncludeSearchPathsText{
+ R"([["/includes", 1, 2], [")" TESTDATA_DIR R"(" ,2 , 3], ["/other/includes", 3, 3]])"};
+ Utils::SmallString projectIncludeSearchPathsText{
+ R"([["/project/includes", 1, 1], ["/other/project/includes", 2, 1]])"};
+ ClangBackEnd::ProjectPartArtefact artefact{R"(["-DFOO"])",
+ R"([["FOO","1", 2],["BAR","1", 1]])",
+ systemIncludeSearchPathsText,
+ projectIncludeSearchPathsText,
+ 74};
+ ClangBackEnd::ProjectPartArtefact emptyArtefact{"", "", "", "", 74};
Utils::optional<ClangBackEnd::ProjectPartArtefact > nullArtefact;
ClangBackEnd::ProjectPartPch projectPartPch{"/path/to/pch", 4};
NiceMock<MockSqliteTransactionBackend> mockSqliteTransactionBackend;
@@ -204,7 +231,11 @@ protected:
Manager collectorManger{generatedFiles};
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()};
- Scheduler indexerScheduler{collectorManger, indexerQueue, progressCounter, 1};
+ Scheduler indexerScheduler{collectorManger,
+ indexerQueue,
+ progressCounter,
+ 1,
+ ClangBackEnd::CallDoInMainThreadAfterFinished::Yes};
SymbolIndexerTaskQueue indexerQueue{indexerScheduler, progressCounter};
ClangBackEnd::SymbolIndexer indexer{indexerQueue,
mockSymbolStorage,
@@ -220,7 +251,25 @@ std::unique_ptr<Data> SymbolIndexer::data;
TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollector)
{
- EXPECT_CALL(mockCollector, setFile(main1PathId, projectPart1.arguments));
+ EXPECT_CALL(mockCollector,
+ setFile(main1PathId,
+ ElementsAre("clang++",
+ "-Wno-pragma-once-outside-header",
+ "-x",
+ "c++-header",
+ "-std=c++14",
+ "-nostdinc",
+ "-nostdlibinc",
+ "-I",
+ "/project/includes",
+ "-I",
+ "/other/project/includes",
+ "-isystem",
+ TESTDATA_DIR,
+ "-isystem",
+ "/other/includes",
+ "-isystem",
+ "/includes")));
indexer.updateProjectParts({projectPart1});
}
@@ -230,14 +279,29 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithPrecompiledHeaderInColl
ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId))).WillByDefault(Return(emptyArtefact));
ON_CALL(mockSymbolStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))).WillByDefault(Return(projectPartPch));
- EXPECT_CALL(mockCollector, setFile(main1PathId,
- ElementsAre(Eq("-I"),
- Eq(TESTDATA_DIR),
- Eq("-Wno-pragma-once-outside-header"),
- Eq("-Xclang"),
- Eq("-include-pch"),
- Eq("-Xclang"),
- Eq("/path/to/pch"))));
+ EXPECT_CALL(mockCollector,
+ setFile(main1PathId,
+ ElementsAre("clang++",
+ "-Wno-pragma-once-outside-header",
+ "-x",
+ "c++-header",
+ "-std=c++14",
+ "-nostdinc",
+ "-nostdlibinc",
+ "-I",
+ "/project/includes",
+ "-I",
+ "/other/project/includes",
+ "-isystem",
+ TESTDATA_DIR,
+ "-isystem",
+ "/other/includes",
+ "-isystem",
+ "/includes",
+ "-Xclang",
+ "-include-pch",
+ "-Xclang",
+ "/path/to/pch")));
indexer.updateProjectParts({projectPart1});
}
@@ -246,10 +310,25 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithoutPrecompiledHeaderInC
{
ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId))).WillByDefault(Return(emptyArtefact));
- EXPECT_CALL(mockCollector, setFile(main1PathId,
- ElementsAre(Eq("-I"),
- Eq(TESTDATA_DIR),
- Eq("-Wno-pragma-once-outside-header"))));
+ EXPECT_CALL(mockCollector,
+ setFile(main1PathId,
+ ElementsAre("clang++",
+ "-Wno-pragma-once-outside-header",
+ "-x",
+ "c++-header",
+ "-std=c++14",
+ "-nostdinc",
+ "-nostdlibinc",
+ "-I",
+ "/project/includes",
+ "-I",
+ "/other/project/includes",
+ "-isystem",
+ TESTDATA_DIR,
+ "-isystem",
+ "/other/includes",
+ "-isystem",
+ "/includes")));
indexer.updateProjectParts({projectPart1});
}
@@ -313,14 +392,21 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddSymbolsAndSourceLocationsInStora
TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartsInStorage)
{
- EXPECT_CALL(mockSymbolStorage, insertOrUpdateProjectPart(Eq("project1"),
- ElementsAre("-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"),
- ElementsAre(CompilerMacro{"BAR", "1", 1}, CompilerMacro{"FOO", "1", 2}),
- ElementsAre("/includes")));
- EXPECT_CALL(mockSymbolStorage, insertOrUpdateProjectPart(Eq("project2"),
- ElementsAre("-I", TESTDATA_DIR, "-x", "c++-header", "-Wno-pragma-once-outside-header"),
- ElementsAre(CompilerMacro{"BAR", "1", 1}, CompilerMacro{"FOO", "0", 2}),
- ElementsAre("/includes")));
+ EXPECT_CALL(mockSymbolStorage,
+ insertOrUpdateProjectPart(
+ Eq("project1"),
+ ElementsAre("-Wno-pragma-once-outside-header"),
+ ElementsAre(CompilerMacro{"BAR", "1", 1}, CompilerMacro{"FOO", "1", 2}),
+ Eq(systemIncludeSearchPaths),
+ Eq(projectIncludeSearchPaths)));
+ EXPECT_CALL(
+ mockSymbolStorage,
+ insertOrUpdateProjectPart(
+ Eq("project2"),
+ ElementsAre("-Wno-pragma-once-outside-header"),
+ ElementsAre(CompilerMacro{"BAR", "1", 1}, CompilerMacro{"FOO", "0", 2}),
+ Eq(systemIncludeSearchPaths),
+ Eq(projectIncludeSearchPaths)));
indexer.updateProjectParts({projectPart1, projectPart2});
}
@@ -328,7 +414,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartsInStorage)
TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartSourcesWithArtifact)
{
ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>("project1"))).WillByDefault(Return(artefact));
- ON_CALL(mockSymbolStorage, insertOrUpdateProjectPart(Eq("project1"), _, _, _)).WillByDefault(Return(-1));
+ ON_CALL(mockSymbolStorage, insertOrUpdateProjectPart(Eq("project1"), _, _, _, _)).WillByDefault(Return(-1));
EXPECT_CALL(mockSymbolStorage, updateProjectPartSources(_, _));
@@ -338,7 +424,7 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartSourcesWithArtifac
TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartSourcesWithoutArtifact)
{
ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>("project2"))).WillByDefault(Return(nullArtefact));
- ON_CALL(mockSymbolStorage, insertOrUpdateProjectPart(Eq("project2"), _, _, _)).WillByDefault(Return(3));
+ ON_CALL(mockSymbolStorage, insertOrUpdateProjectPart(Eq("project2"), _, _, _, _)).WillByDefault(Return(3));
EXPECT_CALL(mockSymbolStorage, updateProjectPartSources(3, ElementsAre(IsFileId(1), IsFileId(23))));
@@ -383,11 +469,35 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithoutProjectPartArtifact)
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId))).WillOnce(Return(nullArtefact));
- EXPECT_CALL(mockSymbolStorage, insertOrUpdateProjectPart(Eq(projectPart1.projectPartId), Eq(projectPart1.arguments), Eq(projectPart1.compilerMacros), Eq(projectPart1.includeSearchPaths))).WillOnce(Return(12));
+ EXPECT_CALL(mockSymbolStorage,
+ insertOrUpdateProjectPart(Eq(projectPart1.projectPartId),
+ Eq(projectPart1.toolChainArguments),
+ Eq(projectPart1.compilerMacros),
+ Eq(projectPart1.systemIncludeSearchPaths),
+ Eq(projectPart1.projectIncludeSearchPaths)))
+ .WillOnce(Return(12));
EXPECT_CALL(mockSymbolStorage, fetchPrecompiledHeader(Eq(12)));
EXPECT_CALL(mockBuildDependenciesStorage, fetchLowestLastModifiedTime(Eq(main1PathId))).Times(0);
EXPECT_CALL(mockSqliteTransactionBackend, commit());
- EXPECT_CALL(mockCollector, setFile(main1PathId, projectPart1.arguments));
+ EXPECT_CALL(mockCollector,
+ setFile(main1PathId,
+ ElementsAre("clang++",
+ "-Wno-pragma-once-outside-header",
+ "-x",
+ "c++-header",
+ "-std=c++14",
+ "-nostdinc",
+ "-nostdlibinc",
+ "-I",
+ "/project/includes",
+ "-I",
+ "/other/project/includes",
+ "-isystem",
+ TESTDATA_DIR,
+ "-isystem",
+ "/other/includes",
+ "-isystem",
+ "/includes")));
EXPECT_CALL(mockCollector, collectSymbols());
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
@@ -406,11 +516,35 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrderWithProjectPartArtifact)
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId))).WillRepeatedly(Return(artefact));
- EXPECT_CALL(mockSymbolStorage, insertOrUpdateProjectPart(Eq(projectPart1.projectPartId), Eq(projectPart1.arguments), Eq(projectPart1.compilerMacros), Eq(projectPart1.includeSearchPaths))).WillOnce(Return(-1));
+ EXPECT_CALL(mockSymbolStorage,
+ insertOrUpdateProjectPart(Eq(projectPart1.projectPartId),
+ Eq(projectPart1.toolChainArguments),
+ Eq(projectPart1.compilerMacros),
+ Eq(projectPart1.systemIncludeSearchPaths),
+ Eq(projectPart1.projectIncludeSearchPaths)))
+ .WillOnce(Return(-1));
EXPECT_CALL(mockSymbolStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId)));
EXPECT_CALL(mockBuildDependenciesStorage, fetchLowestLastModifiedTime(Eq(main1PathId))).WillOnce(Return(-1));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
- EXPECT_CALL(mockCollector, setFile(Eq(main1PathId), Eq(projectPart1.arguments)));
+ EXPECT_CALL(mockCollector,
+ setFile(Eq(main1PathId),
+ ElementsAre("clang++",
+ "-Wno-pragma-once-outside-header",
+ "-x",
+ "c++-header",
+ "-std=c++14",
+ "-nostdinc",
+ "-nostdlibinc",
+ "-I",
+ "/project/includes",
+ "-I",
+ "/other/project/includes",
+ "-isystem",
+ TESTDATA_DIR,
+ "-isystem",
+ "/other/includes",
+ "-isystem",
+ "/includes")));
EXPECT_CALL(mockCollector, collectSymbols());
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockSymbolStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations));
@@ -531,22 +665,57 @@ TEST_F(SymbolIndexer, CompilerMacrosAreDifferent)
ASSERT_TRUE(areDifferent);
}
-TEST_F(SymbolIndexer, IncludeSearchPathsAreDifferent)
+TEST_F(SymbolIndexer, SystemIncludeSearchPathsAreDifferent)
+{
+ ClangBackEnd::IncludeSearchPaths newSystemIncludeSearchPaths{
+ {"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn},
+ {"/other/includes2", 2, ClangBackEnd::IncludeSearchPathType::System}};
+ ClangBackEnd::IncludeSearchPaths newProjectIncludeSearchPaths{
+ {"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User},
+ {"/other/project/includes2", 2, ClangBackEnd::IncludeSearchPathType::User}};
+ ProjectPartContainer projectPart3{
+ "project3",
+ {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
+ {{"BAR", "1", 1}, {"FOO", "1", 2}},
+ {{"/includes", 1, ClangBackEnd::IncludeSearchPathType::BuiltIn},
+ {"/other/includes2", 2, ClangBackEnd::IncludeSearchPathType::System}},
+ Utils::clone(projectIncludeSearchPaths),
+ {header1PathId},
+ {main1PathId},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All};
+ ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>()))
+ .WillByDefault(Return(artefact));
+
+ auto areDifferent = indexer.compilerMacrosOrIncludeSearchPathsAreDifferent(
+ projectPart3, artefact);
+
+ ASSERT_TRUE(areDifferent);
+}
+
+TEST_F(SymbolIndexer, ProjectIncludeSearchPathsAreDifferent)
{
- ProjectPartContainer projectPart3{"project3",
- {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
- {{"BAR", "1", 1}, {"FOO", "1", 2}},
- {"/includes", "/other/includes"},
- {header1PathId},
- {main1PathId}};
- ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact));
+ ProjectPartContainer projectPart3{
+ "project3",
+ {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"},
+ {{"BAR", "1", 1}, {"FOO", "1", 2}},
+ Utils::clone(systemIncludeSearchPaths),
+ {{"/project/includes", 1, ClangBackEnd::IncludeSearchPathType::User},
+ {"/other/project/includes2", 2, ClangBackEnd::IncludeSearchPathType::User}},
+ {header1PathId},
+ {main1PathId},
+ Utils::Language::C,
+ Utils::LanguageVersion::C11,
+ Utils::LanguageExtension::All};
+ ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>()))
+ .WillByDefault(Return(artefact));
- auto areDifferent = indexer.compilerMacrosOrIncludeSearchPathsAreDifferent(projectPart3,
- artefact);
+ auto areDifferent = indexer.compilerMacrosOrIncludeSearchPathsAreDifferent(
+ projectPart3, artefact);
ASSERT_TRUE(areDifferent);
}
-
TEST_F(SymbolIndexer, DontReparseInUpdateProjectPartsIfDefinesAreTheSame)
{
InSequence s;
@@ -554,7 +723,12 @@ TEST_F(SymbolIndexer, DontReparseInUpdateProjectPartsIfDefinesAreTheSame)
EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin());
EXPECT_CALL(mockSymbolStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId))).WillRepeatedly(Return(artefact));
- EXPECT_CALL(mockSymbolStorage, insertOrUpdateProjectPart(Eq(projectPart1.projectPartId), Eq(projectPart1.arguments), Eq(projectPart1.compilerMacros), Eq(projectPart1.includeSearchPaths)));
+ EXPECT_CALL(mockSymbolStorage,
+ insertOrUpdateProjectPart(Eq(projectPart1.projectPartId),
+ Eq(projectPart1.toolChainArguments),
+ Eq(projectPart1.compilerMacros),
+ Eq(projectPart1.systemIncludeSearchPaths),
+ Eq(projectPart1.projectIncludeSearchPaths)));
EXPECT_CALL(mockBuildDependenciesStorage, fetchLowestLastModifiedTime(A<FilePathId>())).WillRepeatedly(Return(QDateTime::currentSecsSinceEpoch()));
EXPECT_CALL(mockSqliteTransactionBackend, commit());
EXPECT_CALL(mockCollector, setFile(_, _)).Times(0);
@@ -649,6 +823,7 @@ TEST_F(SymbolIndexer, OutdatedFilesAreParsedInUpdateProjectParts)
TEST_F(SymbolIndexer, UpToDateFilesAreNotParsedInUpdateProjectParts)
{
indexer.pathsChanged({main1PathId});
+
indexerScheduler.syncTasks();
ON_CALL(mockSymbolStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact));
ON_CALL(mockBuildDependenciesStorage, fetchLowestLastModifiedTime(A<FilePathId>()))
diff --git a/tests/unit/unittest/symbolindexing-test.cpp b/tests/unit/unittest/symbolindexing-test.cpp
index 68a2cb8c65..41bf3a5c3b 100644
--- a/tests/unit/unittest/symbolindexing-test.cpp
+++ b/tests/unit/unittest/symbolindexing-test.cpp
@@ -30,7 +30,7 @@
#include <querysqlitestatementfactory.h>
#include <filepathcaching.h>
-#include <projectpartcontainerv2.h>
+#include <projectpartcontainer.h>
#include <refactoringdatabaseinitializer.h>
#include <QDir>
@@ -45,8 +45,8 @@ using ClangBackEnd::SymbolStorage;
using ClangBackEnd::FilePathCaching;
using ClangBackEnd::FilePathId;
using ClangBackEnd::RefactoringDatabaseInitializer;
-using ClangBackEnd::V2::ProjectPartContainer;
-using ClangBackEnd::V2::ProjectPartContainer;
+using ClangBackEnd::ProjectPartContainer;
+using ClangBackEnd::ProjectPartContainer;
using ClangRefactoring::SymbolQuery;
using ClangRefactoring::QuerySqliteStatementFactory;
using Utils::PathString;
@@ -88,11 +88,15 @@ protected:
Query query{queryFactory};
PathString main1Path = TESTDATA_DIR "/symbolindexing_main1.cpp";
ProjectPartContainer projectPart1{"project1",
- {"cc", "-I", TESTDATA_DIR, "-std=c++1z"},
+ {},
{{"DEFINE", "1", 1}},
- {"/includes"},
+ {{TESTDATA_DIR, 1, ClangBackEnd::IncludeSearchPathType::System}},
+ {},
{},
- {filePathId(main1Path)}};
+ {filePathId(main1Path)},
+ Utils::Language::Cxx,
+ Utils::LanguageVersion::CXX14,
+ Utils::LanguageExtension::None};
};
TEST_F(SymbolIndexing, Locations)
diff --git a/tests/unit/unittest/symbolstorage-test.cpp b/tests/unit/unittest/symbolstorage-test.cpp
index 266540c62b..4a3958212b 100644
--- a/tests/unit/unittest/symbolstorage-test.cpp
+++ b/tests/unit/unittest/symbolstorage-test.cpp
@@ -35,18 +35,21 @@
namespace {
-using Utils::PathString;
-using ClangBackEnd::FilePathId;
using ClangBackEnd::FilePathCachingInterface;
-using ClangBackEnd::SymbolEntries;
-using ClangBackEnd::SymbolEntry;
+using ClangBackEnd::FilePathId;
+using ClangBackEnd::IncludeSearchPath;
+using ClangBackEnd::IncludeSearchPaths;
+using ClangBackEnd::IncludeSearchPathType;
using ClangBackEnd::SourceLocationEntries;
using ClangBackEnd::SourceLocationEntry;
-using ClangBackEnd::SymbolIndex;
using ClangBackEnd::SourceLocationKind;
+using ClangBackEnd::SymbolEntries;
+using ClangBackEnd::SymbolEntry;
+using ClangBackEnd::SymbolIndex;
using ClangBackEnd::SymbolKind;
using Sqlite::Database;
using Sqlite::Table;
+using Utils::PathString;
using Storage = ClangBackEnd::SymbolStorage<MockSqliteDatabase>;
@@ -65,8 +68,7 @@ protected:
MockSqliteWriteStatement &insertNewLocationsInLocationsStatement = storage.m_insertNewLocationsInLocationsStatement;
MockSqliteWriteStatement &deleteNewSymbolsTableStatement = storage.m_deleteNewSymbolsTableStatement;
MockSqliteWriteStatement &deleteNewLocationsTableStatement = storage.m_deleteNewLocationsTableStatement;
- MockSqliteWriteStatement &insertProjectPartStatement = storage.m_insertProjectPartStatement;
- MockSqliteWriteStatement &updateProjectPartStatement = storage.m_updateProjectPartStatement;
+ MockSqliteWriteStatement &insertOrUpdateProjectPartStatement = storage.m_insertOrUpdateProjectPartStatement;
MockSqliteReadStatement &getProjectPartIdStatement = storage.m_getProjectPartIdStatement;
MockSqliteWriteStatement &deleteAllProjectPartsSourcesWithProjectPartIdStatement = storage.m_deleteAllProjectPartsSourcesWithProjectPartIdStatement;
MockSqliteWriteStatement &insertProjectPartSourcesStatement = storage.m_insertProjectPartSourcesStatement;
@@ -78,7 +80,21 @@ protected:
{2, {"function2USR", "function2", SymbolKind::Function}}};
SourceLocationEntries sourceLocations{{1, 3, {42, 23}, SourceLocationKind::Declaration},
{2, 4, {7, 11}, SourceLocationKind::Definition}};
- ClangBackEnd::ProjectPartArtefact artefact{"[\"-DFOO\"]", "{\"FOO\":\"1\"}", "[\"/includes\"]", 74};
+ IncludeSearchPaths systemIncludeSearchPaths{
+ {"/includes", 1, IncludeSearchPathType::BuiltIn},
+ {"/other/includes", 2, IncludeSearchPathType::System}};
+ IncludeSearchPaths projectIncludeSearchPaths{
+ {"/project/includes", 1, IncludeSearchPathType::User},
+ {"/other/project/includes", 2, IncludeSearchPathType::User}};
+ Utils::SmallString systemIncludeSearchPathsText{
+ R"([["/includes",1,2],["/other/includes",2,3]])"};
+ Utils::SmallString projectIncludeSearchPathsText{
+ R"([["/project/includes",1,1],["/other/project/includes",2,1]])"};
+ ClangBackEnd::ProjectPartArtefact artefact{R"(["-DFOO"])",
+ R"([["FOO","1",1]])",
+ systemIncludeSearchPathsText,
+ projectIncludeSearchPathsText,
+ 74};
};
TEST_F(SymbolStorage, CreateAndFillTemporaryLocationsTable)
@@ -167,43 +183,24 @@ TEST_F(SymbolStorage, ConvertStringsToJson)
ASSERT_THAT(jsonText, Eq("[\"foo\",\"bar\",\"foo\"]"));
}
-TEST_F(SymbolStorage, InsertProjectPart)
+TEST_F(SymbolStorage, InsertOrUpdateProjectPart)
{
InSequence sequence;
- ON_CALL(mockDatabase, lastInsertedRowId()).WillByDefault(Return(1));
- EXPECT_CALL(mockDatabase, setLastInsertedRowId(-1));
- EXPECT_CALL(insertProjectPartStatement,
+ EXPECT_CALL(insertOrUpdateProjectPartStatement,
write(TypedEq<Utils::SmallStringView>("project"),
- TypedEq<Utils::SmallStringView>("[\"foo\"]"),
- TypedEq<Utils::SmallStringView>("{\"FOO\":\"1\"}"),
- TypedEq<Utils::SmallStringView>("[\"/includes\"]")));
- EXPECT_CALL(mockDatabase, lastInsertedRowId()).Times(2);
-
- storage.insertOrUpdateProjectPart("project", {"foo"}, {{"FOO", "1", 1}}, {"/includes"});
+ TypedEq<Utils::SmallStringView>(R"(["foo"])"),
+ TypedEq<Utils::SmallStringView>(R"([["FOO","1",1]])"),
+ TypedEq<Utils::SmallStringView>(systemIncludeSearchPathsText),
+ TypedEq<Utils::SmallStringView>(projectIncludeSearchPathsText)));
+ EXPECT_CALL(
+ getProjectPartIdStatement, valueReturnInt32(TypedEq<Utils::SmallStringView>("project")))
+ .WillOnce(Return(74));
+
+ storage.insertOrUpdateProjectPart(
+ "project", {"foo"}, {{"FOO", "1", 1}}, systemIncludeSearchPaths, projectIncludeSearchPaths);
}
-TEST_F(SymbolStorage, UpdateProjectPart)
-{
- InSequence sequence;
- ON_CALL(mockDatabase, lastInsertedRowId()).WillByDefault(Return(-1));
-
- EXPECT_CALL(mockDatabase, setLastInsertedRowId(-1));
- EXPECT_CALL(insertProjectPartStatement,
- write(TypedEq<Utils::SmallStringView>("project"),
- TypedEq<Utils::SmallStringView>("[\"foo\"]"),
- TypedEq<Utils::SmallStringView>("{\"FOO\":\"1\"}"),
- TypedEq<Utils::SmallStringView>("[\"/includes\"]")));
- EXPECT_CALL(mockDatabase, lastInsertedRowId());
- EXPECT_CALL(updateProjectPartStatement,
- write(TypedEq<Utils::SmallStringView>("[\"foo\"]"),
- TypedEq<Utils::SmallStringView>("{\"FOO\":\"1\"}"),
- TypedEq<Utils::SmallStringView>("[\"/includes\"]"),
- TypedEq<Utils::SmallStringView>("project")));
- EXPECT_CALL(mockDatabase, lastInsertedRowId());
-
- storage.insertOrUpdateProjectPart("project", {"foo"}, {{"FOO", "1", 1}}, {"/includes"});
-}
TEST_F(SymbolStorage, UpdateProjectPartSources)
{
diff --git a/tests/unit/unittest/taskscheduler-test.cpp b/tests/unit/unittest/taskscheduler-test.cpp
index 9afc52a724..7b6d0bbcbf 100644
--- a/tests/unit/unittest/taskscheduler-test.cpp
+++ b/tests/unit/unittest/taskscheduler-test.cpp
@@ -68,14 +68,16 @@ protected:
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()};
Scheduler scheduler{mockProcessorManager,
- mockSymbolIndexerTaskQueue,
- progressCounter,
- 4};
+ mockSymbolIndexerTaskQueue,
+ progressCounter,
+ 4,
+ ClangBackEnd::CallDoInMainThreadAfterFinished::Yes};
Scheduler deferredScheduler{mockProcessorManager,
- mockSymbolIndexerTaskQueue,
- progressCounter,
- 4,
- std::launch::deferred};
+ mockSymbolIndexerTaskQueue,
+ progressCounter,
+ 4,
+ ClangBackEnd::CallDoInMainThreadAfterFinished::Yes,
+ std::launch::deferred};
};
TEST_F(TaskScheduler, AddTasks)
@@ -146,6 +148,24 @@ TEST_F(TaskScheduler, FreeSlotsCallsCleanupMethodsAfterTheWorkIsDone)
scheduler.slotUsage();
}
+TEST_F(TaskScheduler, FreeSlotsDoNotCallsDoInMainThreadAfterFinishedAfterTheWorkIsDoneIfForbidden)
+{
+ Scheduler scheduler{mockProcessorManager,
+ mockSymbolIndexerTaskQueue,
+ progressCounter,
+ 4,
+ ClangBackEnd::CallDoInMainThreadAfterFinished::No};
+ scheduler.addTasks({nocall, nocall});
+ scheduler.syncTasks();
+ InSequence s;
+
+ EXPECT_CALL(mockSymbolsCollector, doInMainThreadAfterFinished()).Times(0);
+
+ scheduler.slotUsage();
+ scheduler.syncTasks();
+ QCoreApplication::processEvents();
+}
+
TEST_F(TaskScheduler, FreeSlotsCallsProgressMethodsAfterTheWorkIsDone)
{
scheduler.addTasks({nocall, nocall});
diff --git a/tests/unit/unittest/testenvironment.h b/tests/unit/unittest/testenvironment.h
index 8b6ef89710..a9529c58d5 100644
--- a/tests/unit/unittest/testenvironment.h
+++ b/tests/unit/unittest/testenvironment.h
@@ -44,11 +44,6 @@ public:
return temporaryDirectory.path();
}
- QString clangCompilerPath() const override
- {
- return QString::fromUtf8(CLANG_COMPILER_PATH);
- }
-
uint hardwareConcurrency() const
{
return 2;
diff --git a/tests/unit/unittest/toolchainargumentscache-test.cpp b/tests/unit/unittest/toolchainargumentscache-test.cpp
new file mode 100644
index 0000000000..8f032fa43d
--- /dev/null
+++ b/tests/unit/unittest/toolchainargumentscache-test.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+#include "googletest.h"
+
+#include <toolchainargumentscache.h>
+
+namespace {
+
+using ClangBackEnd::ProjectPartContainer;
+
+MATCHER_P2(IsEntry,
+ projectPartIds,
+ arguments,
+ std::string(negation ? "isn't " : "is ")
+ + PrintToString(ClangBackEnd::ArgumentsEntry(projectPartIds.clone(), arguments)))
+{
+ const ClangBackEnd::ArgumentsEntry &entry= arg;
+
+ return entry.ids == projectPartIds && entry.arguments == arguments;
+}
+
+class ToolChainArgumentsCache : public testing::Test
+{
+public:
+ ClangBackEnd::ToolChainsArgumentsCache cache;
+ ProjectPartContainer projectPart1{"project1", {}, {}, {}, {}, {}, {}, {}, {}, {}};
+ ProjectPartContainer projectPart2{"project2", {}, {}, {}, {}, {}, {}, {}, {}, {}};
+ ProjectPartContainer projectPart3{"project3", {}, {}, {}, {}, {}, {}, {}, {}, {}};
+ ProjectPartContainer projectPart4{"project4", {}, {}, {}, {}, {}, {}, {}, {}, {}};
+ Utils::SmallStringVector arguments1{"yi", "er"};
+ Utils::SmallStringVector arguments2{"san", "se"};
+};
+
+TEST_F(ToolChainArgumentsCache, ArgumentsDoesNotExistForProjectPartId)
+{
+ cache.update({projectPart2, projectPart4}, arguments2);
+
+ ASSERT_THAT(cache.arguments({projectPart1.projectPartId}), IsEmpty());
+}
+
+TEST_F(ToolChainArgumentsCache, AddNewArguments)
+{
+ cache.update({projectPart2, projectPart4}, arguments2);
+
+ cache.update({projectPart1, projectPart3}, arguments1);
+
+ ASSERT_THAT(
+ cache.arguments({projectPart1.projectPartId}),
+ ElementsAre(IsEntry(Utils::SmallStringVector{projectPart1.projectPartId}, arguments1)));
+}
+
+TEST_F(ToolChainArgumentsCache, AddDifferentProjectParts)
+{
+ cache.update({projectPart1, projectPart3}, arguments1);
+
+ cache.update({projectPart2, projectPart4}, arguments1);
+
+ ASSERT_THAT(
+ cache.arguments(Utils::SmallStringVector{projectPart2.projectPartId}),
+ ElementsAre(IsEntry(Utils::SmallStringVector{projectPart2.projectPartId}, arguments1)));
+}
+
+TEST_F(ToolChainArgumentsCache, AddDifferentProjectPartsReverseOrder)
+{
+ cache.update({projectPart2, projectPart3}, arguments1);
+
+ cache.update({projectPart1, projectPart4}, arguments1);
+
+ ASSERT_THAT(
+ cache.arguments(Utils::SmallStringVector{projectPart2.projectPartId}),
+ ElementsAre(IsEntry(Utils::SmallStringVector{projectPart2.projectPartId}, arguments1)));
+}
+
+TEST_F(ToolChainArgumentsCache, AddDifferentProjectPartsDoesNotRemoveOldEntry)
+{
+ cache.update({projectPart1, projectPart3}, arguments1);
+
+ cache.update({projectPart2, projectPart4}, arguments1);
+
+ ASSERT_THAT(
+ cache.arguments(Utils::SmallStringVector{projectPart1.projectPartId}),
+ ElementsAre(IsEntry(Utils::SmallStringVector{projectPart1.projectPartId}, arguments1)));
+}
+
+TEST_F(ToolChainArgumentsCache, AddSameArgumentsDoesNotIncreseEntryCount)
+{
+ cache.update({projectPart1, projectPart3}, arguments1);
+
+ cache.update({projectPart2, projectPart4}, arguments1);
+
+ ASSERT_THAT(cache.size(), 1);
+}
+
+TEST_F(ToolChainArgumentsCache, AddDifferentArgumentsDoesIncreseEntryCount)
+{
+ cache.update({projectPart1, projectPart3}, arguments1);
+
+ cache.update({projectPart2, projectPart4}, arguments2);
+
+ ASSERT_THAT(cache.size(), 2);
+}
+
+TEST_F(ToolChainArgumentsCache, RemoveIdsFromOtherEntries)
+{
+ cache.update({projectPart2, projectPart4}, arguments1);
+ cache.update({projectPart1, projectPart3}, arguments1);
+
+ cache.update({projectPart2, projectPart4}, arguments2);
+
+ ASSERT_THAT(
+ cache.arguments(Utils::SmallStringVector{projectPart2.projectPartId}),
+ ElementsAre(IsEntry(Utils::SmallStringVector{projectPart2.projectPartId}, arguments2)));
+}
+
+TEST_F(ToolChainArgumentsCache, RemoveIdsFromOtherEntriesWithArgumentsAlreadyExists)
+{
+ cache.update({projectPart2, projectPart4}, arguments1);
+ cache.update({projectPart1, projectPart3}, arguments2);
+
+ cache.update({projectPart2, projectPart4}, arguments2);
+
+ ASSERT_THAT(
+ cache.arguments({projectPart2.projectPartId}),
+ ElementsAre(IsEntry(Utils::SmallStringVector{projectPart2.projectPartId}, arguments2)));
+}
+
+TEST_F(ToolChainArgumentsCache, RemoveEntryIfEmpty)
+{
+ cache.update({projectPart2, projectPart4}, arguments2);
+ cache.update({projectPart1, projectPart3}, arguments1);
+
+ cache.update({projectPart2, projectPart4}, arguments1);
+
+ ASSERT_THAT(cache.size(), 1);
+}
+
+TEST_F(ToolChainArgumentsCache, GetMutipleEntries)
+{
+ cache.update({projectPart2, projectPart4}, arguments1);
+ cache.update({projectPart1, projectPart3}, arguments2);
+
+ auto arguments = cache.arguments(
+ {projectPart1.projectPartId, projectPart2.projectPartId, projectPart3.projectPartId});
+
+ ASSERT_THAT(
+ arguments,
+ ElementsAre(IsEntry(Utils::SmallStringVector{projectPart2.projectPartId}, arguments1),
+ IsEntry(Utils::SmallStringVector{projectPart1.projectPartId,
+ projectPart3.projectPartId},
+ arguments2)));
+}
+
+TEST_F(ToolChainArgumentsCache, RemoveMutipleIds)
+{
+ cache.update({projectPart2, projectPart4}, arguments1);
+ cache.update({projectPart1, projectPart3}, arguments2);
+
+ cache.remove({projectPart1.projectPartId, projectPart2.projectPartId});
+
+ ASSERT_THAT(
+ cache.arguments(
+ {projectPart1.projectPartId, projectPart2.projectPartId, projectPart3.projectPartId}),
+ ElementsAre(IsEntry(Utils::SmallStringVector{projectPart3.projectPartId}, arguments2)));
+}
+
+TEST_F(ToolChainArgumentsCache, RemoveEntriesIfEntryIsEmptyAfterRemovingIds)
+{
+ cache.update({projectPart2, projectPart4}, arguments1);
+ cache.update({projectPart1, projectPart3}, arguments2);
+
+ cache.remove({projectPart1.projectPartId, projectPart3.projectPartId});
+
+ ASSERT_THAT(cache.size(), 1);
+}
+
+} // namespace
diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro
index f6eded4a58..431207371d 100644
--- a/tests/unit/unittest/unittest.pro
+++ b/tests/unit/unittest/unittest.pro
@@ -99,7 +99,6 @@ SOURCES += \
sourcesmanager-test.cpp \
symbolindexertaskqueue-test.cpp \
refactoringprojectupdater-test.cpp \
- projectpartqueue-test.cpp \
processormanager-test.cpp \
taskscheduler-test.cpp \
compileroptionsbuilder-test.cpp \
@@ -111,7 +110,10 @@ SOURCES += \
usedmacrofilter-test.cpp \
pchtasksmerger-test.cpp \
pchtaskqueue-test.cpp \
- headerpathfilter-test.cpp
+ commandlinebuilder-test.cpp \
+ headerpathfilter-test.cpp \
+ toolchainargumentscache-test.cpp \
+ modifiedtimechecker-test.cpp
!isEmpty(LIBCLANG_LIBS) {
SOURCES += \
@@ -262,7 +264,8 @@ HEADERS += \
mockbuilddependenciesstorage.h \
mockbuilddependencygenerator.h \
mockpchtasksmerger.h \
- mockpchtaskqueue.h
+ mockpchtaskqueue.h \
+ mockpchtaskgenerator.h
!isEmpty(LIBCLANG_LIBS) {
HEADERS += \
diff --git a/tests/unit/unittest/usedmacrofilter-test.cpp b/tests/unit/unittest/usedmacrofilter-test.cpp
index 93a29d9c9a..871d4a8535 100644
--- a/tests/unit/unittest/usedmacrofilter-test.cpp
+++ b/tests/unit/unittest/usedmacrofilter-test.cpp
@@ -69,6 +69,20 @@ TEST_F(UsedMacroFilter, ProjectIncludes)
ASSERT_THAT(filter.projectIncludes, ElementsAre(FilePathId{3}, FilePathId{5}));
}
+TEST_F(UsedMacroFilter, TopSystemIncludes)
+{
+ ClangBackEnd::UsedMacroFilter filter(includes, usedMacros);
+
+ ASSERT_THAT(filter.topSystemIncludes, ElementsAre(FilePathId{4}));
+}
+
+TEST_F(UsedMacroFilter, TopProjectIncludes)
+{
+ ClangBackEnd::UsedMacroFilter filter(includes, usedMacros);
+
+ ASSERT_THAT(filter.topProjectIncludes, ElementsAre(FilePathId{5}));
+}
+
TEST_F(UsedMacroFilter, SystemUsedMacros)
{
ClangBackEnd::UsedMacroFilter filter(includes, usedMacros);