ClangPchManager: Extend PchTaskGenerator

It's generating now PchTasks for project and system includes and call the
merger directly.

Change-Id: I966a9a72e1b915255d95b713b66e92d36d85d79b
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
This commit is contained in:
Marco Bubke
2018-11-27 11:49:58 +01:00
parent f6b8302efd
commit 299a163b18
13 changed files with 228 additions and 94 deletions

View File

@@ -232,7 +232,7 @@ public:
database
};
mutable ReadStatement fetchSourceDependenciesStatement{
"WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT dependencySourceId FROM sourceDependencies, collectedDependencies WHERE sourceDependencies.sourceId == collectedDependencies.sourceId) SELECT sourceId, buildDependencyTimeStamp, sourceType FROM collectedDependencies NATURAL JOIN projectPartsSources NATURAL JOIN fileStatuses WHERE projectPartId = ?",
"WITH RECURSIVE collectedDependencies(sourceId) AS (VALUES(?) UNION SELECT dependencySourceId FROM sourceDependencies, collectedDependencies WHERE sourceDependencies.sourceId == collectedDependencies.sourceId) SELECT sourceId, buildDependencyTimeStamp, sourceType FROM collectedDependencies NATURAL JOIN projectPartsSources NATURAL JOIN fileStatuses WHERE projectPartId = ? ORDER BY sourceId",
database
};
mutable ReadStatement fetchProjectPartIdStatement{
@@ -240,7 +240,7 @@ public:
database
};
mutable ReadStatement fetchUsedMacrosStatement{
"SELECT macroName, sourceId FROM usedMacros WHERE sourceId = ?",
"SELECT macroName, sourceId FROM usedMacros WHERE sourceId = ? ORDER BY sourceId, macroName",
database
};
};

View File

@@ -44,6 +44,14 @@ public:
sourceDependencies.clear();
}
friend bool operator==(const BuildDependency &first, const BuildDependency &second)
{
return first.includes == second.includes && first.usedMacros == second.usedMacros
&& first.sourceFiles == second.sourceFiles
&& first.sourceDependencies == second.sourceDependencies
&& first.fileStatuses == second.fileStatuses;
}
public:
SourceEntries includes;
UsedMacros usedMacros;

View File

@@ -34,7 +34,8 @@ HEADERS += \
$$PWD/sourceentry.h \
$$PWD/builddependenciesstorage.h \
$$PWD/builddependencygeneratorinterface.h \
$$PWD/usedmacrofilter.h
$$PWD/usedmacrofilter.h \
$$PWD/pchtasksmergerinterface.h
!isEmpty(LIBTOOLING_LIBS) {
SOURCES += \

View File

@@ -27,6 +27,8 @@
#include "builddependency.h"
#include <compilermacro.h>
#include <utils/smallstringvector.h>
namespace ClangBackEnd {
@@ -34,15 +36,22 @@ namespace ClangBackEnd {
class PchTask
{
public:
PchTask(Utils::SmallStringVector &&ids, BuildDependency &&buildDependency)
: ids(std::move(ids)),
buildDependency(std::move(buildDependency))
{
}
PchTask(Utils::SmallString &&projectPartId,
FilePathIds &&includes,
CompilerMacros &&compilerMacros,
UsedMacros &&usedMacros)
: projectPartId(projectPartId)
, includes(includes)
, compilerMacros(compilerMacros)
, usedMacros(usedMacros)
{}
Utils::SmallStringVector ids;
BuildDependency buildDependency;
Utils::SmallString projectPartId;
Utils::SmallStringVector dependentIds;
FilePathIds includes;
CompilerMacros compilerMacros;
UsedMacros usedMacros;
};
using PchTasks = std::vector<PchTask>;
}
} // namespace ClangBackEnd

View File

@@ -26,22 +26,33 @@
#include "pchtaskgenerator.h"
#include "builddependenciesproviderinterface.h"
#include "pchtasksmergerinterface.h"
#include "usedmacrofilter.h"
#include <utils/algorithm.h>
namespace ClangBackEnd {
PchTasks PchTaskGenerator::create(V2::ProjectPartContainers &&projectParts)
void PchTaskGenerator::create(V2::ProjectPartContainers &&projectParts)
{
PchTasks tasks;
tasks.reserve(projectParts.size() * 2);
for (auto &projectPart : projectParts) {
tasks.emplace_back(std::initializer_list<Utils::SmallString>{{projectPart.projectPartId}},
m_buildDependenciesProvider.create(projectPart));
}
BuildDependency buildDependency = m_buildDependenciesProvider.create(projectPart);
UsedMacroFilter filter{buildDependency.includes, buildDependency.usedMacros};
return tasks;
filter.filter(projectPart.compilerMacros);
m_pchTasksMergerInterface.addTask({projectPart.projectPartId.clone(),
std::move(filter.systemIncludes),
std::move(filter.systemCompilerMacros),
std::move(filter.systemUsedMacros)
},
{std::move(projectPart.projectPartId),
std::move(filter.projectIncludes),
std::move(filter.projectCompilerMacros),
std::move(filter.projectUsedMacros)});
}
}
} // namespace ClangBackEnd

View File

@@ -31,19 +31,24 @@
namespace ClangBackEnd {
class PchTasksMergerInterface;
class BuildDependenciesProviderInterface;
class PchTaskGenerator
{
public:
PchTaskGenerator(BuildDependenciesProviderInterface &buildDependenciesProvider)
PchTaskGenerator(BuildDependenciesProviderInterface &buildDependenciesProvider,
PchTasksMergerInterface &pchTasksMergerInterface)
: m_buildDependenciesProvider(buildDependenciesProvider)
, m_pchTasksMergerInterface(pchTasksMergerInterface)
{}
PchTasks create(V2::ProjectPartContainers &&projectParts);
void create(V2::ProjectPartContainers &&projectParts);
private:
BuildDependenciesProviderInterface &m_buildDependenciesProvider;
PchTasksMergerInterface &m_pchTasksMergerInterface;
};

View File

@@ -0,0 +1,39 @@
/****************************************************************************
**
** 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 "pchtask.h"
namespace ClangBackEnd {
class PchTasksMergerInterface
{
public:
virtual void addTask(PchTask &&systemTask, PchTask &&projectTask) = 0;
protected:
~PchTasksMergerInterface() = default;
};
} // namespace ClangBackEnd

View File

@@ -43,31 +43,20 @@ public:
UsedMacroFilter(const SourceEntries &includes, const UsedMacros &usedMacros)
{
Includes filteredIncludes = filterIncludes(includes);
m_systemUsedMacros = filterUsedMarcos(usedMacros, filteredIncludes.system);
m_projectUsedMacros = filterUsedMarcos(usedMacros, filteredIncludes.project);
filterIncludes(includes);
systemUsedMacros = filterUsedMarcos(usedMacros, systemIncludes);
projectUsedMacros = filterUsedMarcos(usedMacros, projectIncludes);
}
static Includes filterIncludes(const SourceEntries &includes)
void filterIncludes(const SourceEntries &includes)
{
Includes result;
result.system.reserve(includes.size());
result.project.reserve(includes.size());
systemIncludes.reserve(includes.size());
projectIncludes.reserve(includes.size());
for (SourceEntry include : includes)
filterInclude(include, result);
return result;
filterInclude(include);
}
const Utils::PathStringVector &projectUsedMacros() const { return m_projectUsedMacros; }
const Utils::PathStringVector &systemUsedMacros() const { return m_systemUsedMacros; }
const CompilerMacros &projectCompilerMacros() const { return m_projectCompilerMacros; }
const CompilerMacros &systemCompilerMacros() const { return m_systemCompilerMacros; }
void filter(const CompilerMacros &compilerMacros)
{
CompilerMacros indexedCompilerMacro = compilerMacros;
@@ -78,40 +67,39 @@ public:
return std::tie(first.key, first.value) < std::tie(second.key, second.value);
});
m_systemCompilerMacros = filtercompilerMacros(indexedCompilerMacro, m_systemUsedMacros);
m_projectCompilerMacros = filtercompilerMacros(indexedCompilerMacro, m_projectUsedMacros);
systemCompilerMacros = filtercompilerMacros(indexedCompilerMacro, systemUsedMacros);
projectCompilerMacros = filtercompilerMacros(indexedCompilerMacro, projectUsedMacros);
}
private:
static void filterInclude(SourceEntry include, Includes &result)
void filterInclude(SourceEntry include)
{
switch (include.sourceType) {
case SourceType::TopSystemInclude:
case SourceType::SystemInclude:
result.system.emplace_back(include.sourceId);
systemIncludes.emplace_back(include.sourceId);
break;
case SourceType::TopProjectInclude:
case SourceType::ProjectInclude:
result.project.emplace_back(include.sourceId);
projectIncludes.emplace_back(include.sourceId);
break;
case SourceType::UserInclude:
break;
}
}
static Utils::PathStringVector filterUsedMarcos(const UsedMacros &usedMacros,
const FilePathIds &filePathId)
static UsedMacros filterUsedMarcos(const UsedMacros &usedMacros, const FilePathIds &filePathId)
{
class BackInserterIterator : public std::back_insert_iterator<Utils::PathStringVector>
class BackInserterIterator : public std::back_insert_iterator<UsedMacros>
{
public:
BackInserterIterator(Utils::PathStringVector &container)
: std::back_insert_iterator<Utils::PathStringVector>(container)
BackInserterIterator(UsedMacros &container)
: std::back_insert_iterator<UsedMacros>(container)
{}
BackInserterIterator &operator=(const UsedMacro &usedMacro)
{
container->push_back(usedMacro.macroName);
container->push_back(usedMacro);
return *this;
}
@@ -132,7 +120,7 @@ private:
}
};
Utils::PathStringVector filtertedMacros;
UsedMacros filtertedMacros;
filtertedMacros.reserve(usedMacros.size());
std::set_intersection(usedMacros.begin(),
@@ -142,26 +130,30 @@ private:
BackInserterIterator(filtertedMacros),
Compare{});
std::sort(filtertedMacros.begin(), filtertedMacros.end());
std::sort(filtertedMacros.begin(),
filtertedMacros.end(),
[](const UsedMacro &first, const UsedMacro &second) {
return first.macroName < second.macroName;
});
return filtertedMacros;
}
static CompilerMacros filtercompilerMacros(const CompilerMacros &indexedCompilerMacro,
const Utils::PathStringVector &usedMacros)
const UsedMacros &usedMacros)
{
struct Compare
{
bool operator()(const Utils::PathString &usedMacro,
bool operator()(const UsedMacro &usedMacro,
const CompilerMacro &compileMacro)
{
return usedMacro < compileMacro.key;
return usedMacro.macroName < compileMacro.key;
}
bool operator()(const CompilerMacro &compileMacro,
const Utils::PathString &usedMacro)
const UsedMacro &usedMacro)
{
return compileMacro.key < usedMacro;
return compileMacro.key < usedMacro.macroName;
}
};
@@ -175,20 +167,16 @@ private:
std::back_inserter(filtertedCompilerMacros),
Compare{});
std::sort(filtertedCompilerMacros.begin(),
filtertedCompilerMacros.end(),
[](const CompilerMacro &first, const CompilerMacro &second) {
return first.index < second.index;
});
return filtertedCompilerMacros;
}
private:
Utils::PathStringVector m_projectUsedMacros;
Utils::PathStringVector m_systemUsedMacros;
CompilerMacros m_projectCompilerMacros;
CompilerMacros m_systemCompilerMacros;
public:
FilePathIds projectIncludes;
FilePathIds systemIncludes;
UsedMacros projectUsedMacros;
UsedMacros systemUsedMacros;
CompilerMacros projectCompilerMacros;
CompilerMacros systemCompilerMacros;
};
} // namespace ClangBackEnd

View File

@@ -907,10 +907,8 @@ std::ostream &operator<<(std::ostream &out, const ProjectPartArtefact &projectPa
std::ostream &operator<<(std::ostream &out, const CompilerMacro &compilerMacro)
{
return out << "("
<< compilerMacro.key << ", "
<< compilerMacro.value
<< ")";
return out << "(" << compilerMacro.key << ", " << compilerMacro.value << ", "
<< compilerMacro.index << ")";
}
std::ostream &operator<<(std::ostream &out, const SymbolEntry &entry)
@@ -1030,11 +1028,13 @@ std::ostream &operator<<(std::ostream &out, const ProgressMessage &message)
std::ostream &operator<<(std::ostream &out, const PchCreatorIncludes &includes)
{
return out << "(" << includes.includeIds << ", " << includes.topIncludeIds << ", " << includes.topSystemIncludeIds << ")";
return out << "(" << includes.includeIds << ", " << includes.topIncludeIds << ", "
<< includes.topSystemIncludeIds << ")";
}
std::ostream &operator<<(std::ostream &out, const PchTask &task)
{
return out << "(" << task.ids << ", " << task.buildDependency << ")";
return out << "(" << task.projectPartId << ", " << task.dependentIds << ", " << task.includes
<< ", " << task.compilerMacros << ", " << task.usedMacros << ")";
}
std::ostream &operator<<(std::ostream &out, const BuildDependency &dependency)

View File

@@ -0,0 +1,43 @@
/****************************************************************************
**
** 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 <pchtasksmergerinterface.h>
class MockPchTasksMerger : public ClangBackEnd::PchTasksMergerInterface
{
public:
MOCK_METHOD2(addTask,
void(const ClangBackEnd::PchTask &systemPchTask,
const ClangBackEnd::PchTask &projectPchTask));
void addTask(ClangBackEnd::PchTask &&systemPchTask, ClangBackEnd::PchTask &&projectPchTask)
{
addTask(systemPchTask, projectPchTask);
}
};

View File

@@ -26,6 +26,7 @@
#include "googletest.h"
#include "mockbuilddependenciesprovider.h"
#include "mockpchtasksmerger.h"
#include <pchtaskgenerator.h>
@@ -33,37 +34,65 @@ namespace {
using ClangBackEnd::BuildDependency;
using ClangBackEnd::BuildDependencies;
using ClangBackEnd::CompilerMacro;
using ClangBackEnd::FilePathId;
using ClangBackEnd::PchTask;
using ClangBackEnd::SourceEntries;
using ClangBackEnd::SourceType;
using ClangBackEnd::UsedMacro;
using ClangBackEnd::UsedMacros;
class PchTaskGenerator : public testing::Test
{
protected:
NiceMock<MockBuildDependenciesProvider> mockBuildDependenciesProvider;
ClangBackEnd::PchTaskGenerator generator{mockBuildDependenciesProvider};
NiceMock<MockPchTasksMerger> mockPchTaskMerger;
ClangBackEnd::PchTaskGenerator generator{mockBuildDependenciesProvider, mockPchTaskMerger};
ClangBackEnd::V2::ProjectPartContainer projectPart1{"ProjectPart1",
{"--yi"},
{{"YI", "1", 1}},
{{"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}}};
SourceEntries firstSources{{1, SourceType::UserInclude, 1}, {2, SourceType::UserInclude, 1}, {10, SourceType::UserInclude, 1}};
BuildDependency buildDependency{firstSources, {}};
SourceEntries firstSources{{1, SourceType::ProjectInclude, 1},
{2, SourceType::UserInclude, 1},
{3, SourceType::TopProjectInclude, 1},
{4, SourceType::SystemInclude, 1},
{5, SourceType::TopSystemInclude, 1}};
UsedMacros usedMacros{{"LIANG", 0},{"YI", 1}, {"ER", 2}, {"SAN", 3}, {"SE", 4}, {"WU", 5}};
BuildDependency buildDependency{firstSources, usedMacros, {}, {}, {}};
};
TEST_F(PchTaskGenerator, Create)
{
ON_CALL(mockBuildDependenciesProvider, create(_)).WillByDefault(Return(buildDependency));
auto tasks = generator.create({projectPart1});
EXPECT_CALL(mockPchTaskMerger,
addTask(AllOf(Field(&PchTask::projectPartId, Eq("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(&PchTask::projectPartId, Eq("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})))));
ASSERT_THAT(tasks,
ElementsAre(
AllOf(Field(&PchTask::ids, ElementsAre("ProjectPart1")),
Field(&PchTask::buildDependency,
Field(&BuildDependency::includes, firstSources)))));
generator.create({projectPart1});
}
}

View File

@@ -257,7 +257,8 @@ HEADERS += \
mockbuilddependenciesprovider.h \
mockmodifiedtimechecker.h \
mockbuilddependenciesstorage.h \
mockbuilddependencygenerator.h
mockbuilddependencygenerator.h \
mockpchtasksmerger.h
!isEmpty(LIBCLANG_LIBS) {
HEADERS += \

View File

@@ -57,30 +57,30 @@ protected:
TEST_F(UsedMacroFilter, SystemIncludes)
{
auto result = ClangBackEnd::UsedMacroFilter::filterIncludes(includes);
ClangBackEnd::UsedMacroFilter filter(includes, usedMacros);
ASSERT_THAT(result.system, ElementsAre(FilePathId{2}, FilePathId{4}));
ASSERT_THAT(filter.systemIncludes, ElementsAre(FilePathId{2}, FilePathId{4}));
}
TEST_F(UsedMacroFilter, ProjectIncludes)
{
auto result = ClangBackEnd::UsedMacroFilter::filterIncludes(includes);
ClangBackEnd::UsedMacroFilter filter(includes, usedMacros);
ASSERT_THAT(result.project, ElementsAre(FilePathId{3}, FilePathId{5}));
ASSERT_THAT(filter.projectIncludes, ElementsAre(FilePathId{3}, FilePathId{5}));
}
TEST_F(UsedMacroFilter, SystemUsedMacros)
{
ClangBackEnd::UsedMacroFilter filter(includes, usedMacros);
ASSERT_THAT(filter.systemUsedMacros(), ElementsAre("ER", "SE"));
ASSERT_THAT(filter.systemUsedMacros, ElementsAre(UsedMacro{"ER", 2}, UsedMacro{"SE", 4}));
}
TEST_F(UsedMacroFilter, ProjectUsedMacros)
{
ClangBackEnd::UsedMacroFilter filter(includes, usedMacros);
ASSERT_THAT(filter.projectUsedMacros(), ElementsAre("WU", "SAN"));
ASSERT_THAT(filter.projectUsedMacros, ElementsAre(UsedMacro{"WU", 5}, UsedMacro{"SAN", 3}));
}
TEST_F(UsedMacroFilter, SystemCompileMacros)
@@ -89,7 +89,7 @@ TEST_F(UsedMacroFilter, SystemCompileMacros)
filter.filter(compileMacros);
ASSERT_THAT(filter.systemCompilerMacros(),
ASSERT_THAT(filter.systemCompilerMacros,
ElementsAre(CompilerMacro{"ER", "2", 2}, CompilerMacro{"SE", "4", 4}));
}
@@ -99,8 +99,8 @@ TEST_F(UsedMacroFilter, ProjectCompileMacros)
filter.filter(compileMacros);
ASSERT_THAT(filter.projectCompilerMacros(),
ElementsAre(CompilerMacro{"SAN", "3", 3}, CompilerMacro{"WU", "5", 5}));
ASSERT_THAT(filter.projectCompilerMacros,
ElementsAre(CompilerMacro{"WU", "5", 5}, CompilerMacro{"SAN", "3", 3}));
}
} // namespace