diff --git a/src/libs/clangsupport/precompiledheadersupdatedmessage.h b/src/libs/clangsupport/precompiledheadersupdatedmessage.h index 5a21b995df2..9c17a3c9da2 100644 --- a/src/libs/clangsupport/precompiledheadersupdatedmessage.h +++ b/src/libs/clangsupport/precompiledheadersupdatedmessage.h @@ -33,7 +33,11 @@ class PrecompiledHeadersUpdatedMessage { public: PrecompiledHeadersUpdatedMessage() = default; - PrecompiledHeadersUpdatedMessage(std::vector &&projectPartPchs) + PrecompiledHeadersUpdatedMessage(ProjectPartPch projectPartPch) + { + projectPartPchs.push_back(projectPartPch); + } + PrecompiledHeadersUpdatedMessage(ProjectPartPchs &&projectPartPchs) : projectPartPchs(std::move(projectPartPchs)) {} @@ -68,7 +72,7 @@ public: } public: - std::vector projectPartPchs; + ProjectPartPchs projectPartPchs; }; CLANGSUPPORT_EXPORT QDebug operator<<(QDebug debug, const PrecompiledHeadersUpdatedMessage &message); diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp index 3f858b50ee3..9b8683bcac5 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp @@ -111,6 +111,8 @@ Utils::SmallStringVector PchCreator::generateClangCompilerArguments(const PchTas void PchCreator::generatePch(PchTask &&pchTask) { + m_projectPartPch.projectPartId = pchTask.projectPartId(); + m_projectPartPch.lastModified = QDateTime::currentSecsSinceEpoch(); auto content = generatePchIncludeFileContent(pchTask.includes); auto pchOutputPath = generatePchFilePath(); @@ -121,8 +123,6 @@ void PchCreator::generatePch(PchTask &&pchTask) m_clangTool.addFile(std::move(headerFilePath), content.clone(), std::move(commandLine)); bool success = generatePch(NativeFilePath{headerFilePath}, content); - m_projectPartPch.projectPartId = pchTask.projectPartId(); - if (success) { m_sources = pchTask.sources; m_projectPartPch.pchPath = std::move(pchOutputPath); @@ -168,17 +168,19 @@ void PchCreator::clear() void PchCreator::doInMainThreadAfterFinished() { - FilePathIds existingSources; - existingSources.reserve(m_sources.size()); - std::set_difference(m_sources.begin(), - m_sources.end(), - m_generatedFilePathIds.begin(), - m_generatedFilePathIds.end(), - std::back_inserter(existingSources)); - m_buildDependenciesStorage.updatePchCreationTimeStamp(m_projectPartPch.lastModified, - m_projectPartPch.projectPartId); - m_clangPathwatcher.updateIdPaths({{m_projectPartPch.projectPartId, existingSources}}); - m_pchManagerClient.precompiledHeadersUpdated(ProjectPartPchs{m_projectPartPch}); + if (m_projectPartPch.projectPartId.isValid()) { + FilePathIds existingSources; + existingSources.reserve(m_sources.size()); + std::set_difference(m_sources.begin(), + m_sources.end(), + m_generatedFilePathIds.begin(), + m_generatedFilePathIds.end(), + std::back_inserter(existingSources)); + m_buildDependenciesStorage.updatePchCreationTimeStamp(m_projectPartPch.lastModified, + m_projectPartPch.projectPartId); + m_clangPathwatcher.updateIdPaths({{m_projectPartPch.projectPartId, existingSources}}); + m_pchManagerClient.precompiledHeadersUpdated({m_projectPartPch}); + } } const FilePathCaching &PchCreator::filePathCache() diff --git a/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp b/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp index 1bf21712fd8..d2507ee8641 100644 --- a/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchtaskqueue.cpp @@ -144,15 +144,19 @@ std::vector PchTaskQueue::createProjectTasks(PchTasks &&pchT auto convert = [this](auto &&pchTask) { return [pchTask = std::move(pchTask), this](PchCreatorInterface &pchCreator) mutable { const auto projectPartId = pchTask.projectPartId(); - pchTask.systemPchPath = m_precompiledHeaderStorage.fetchSystemPrecompiledHeaderPath( - projectPartId); - pchCreator.generatePch(std::move(pchTask)); - const auto &projectPartPch = pchCreator.projectPartPch(); - if (projectPartPch.pchPath.empty()) { - m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(projectPartId); + if (pchTask.includes.size()) { + pchTask.systemPchPath = m_precompiledHeaderStorage.fetchSystemPrecompiledHeaderPath( + projectPartId); + pchCreator.generatePch(std::move(pchTask)); + const auto &projectPartPch = pchCreator.projectPartPch(); + if (projectPartPch.pchPath.empty()) { + m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(projectPartId); + } else { + m_precompiledHeaderStorage.insertProjectPrecompiledHeader( + projectPartId, projectPartPch.pchPath, projectPartPch.lastModified); + } } else { - m_precompiledHeaderStorage.insertProjectPrecompiledHeader( - projectPartId, projectPartPch.pchPath, projectPartPch.lastModified); + m_precompiledHeaderStorage.deleteProjectPrecompiledHeader(projectPartId); } }; }; @@ -173,14 +177,17 @@ std::vector PchTaskQueue::createSystemTasks(PchTasks &&pchTa auto convert = [this](auto &&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(); - if (projectPartPch.pchPath.empty()) { - m_precompiledHeaderStorage.deleteSystemPrecompiledHeaders(projectPartIds); + if (pchTask.includes.size()) { + pchCreator.generatePch(std::move(pchTask)); + const auto &projectPartPch = pchCreator.projectPartPch(); + if (projectPartPch.pchPath.empty()) { + m_precompiledHeaderStorage.deleteSystemPrecompiledHeaders(projectPartIds); + } else { + m_precompiledHeaderStorage.insertSystemPrecompiledHeaders( + projectPartIds, projectPartPch.pchPath, projectPartPch.lastModified); + } } else { - m_precompiledHeaderStorage.insertSystemPrecompiledHeaders(projectPartIds, - projectPartPch.pchPath, - projectPartPch.lastModified); + m_precompiledHeaderStorage.deleteSystemPrecompiledHeaders(projectPartIds); } }; }; diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index 5e16948387c..9c40b7fea76 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -243,6 +243,15 @@ TEST_F(PchCreatorVerySlowTest, PchCreationTimeStampsAreUpdated) creator.doInMainThreadAfterFinished(); } +TEST_F(PchCreator, DoNothingInTheMainThreadIfGenerateWasNotCalled) +{ + EXPECT_CALL(mockBuildDependenciesStorage, updatePchCreationTimeStamp(_, _)).Times(0); + EXPECT_CALL(mockClangPathWatcher, updateIdPaths(_)).Times(0); + EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(_)).Times(0); + + creator.doInMainThreadAfterFinished(); +} + TEST_F(PchCreatorVerySlowTest, ProjectPartPchForCreatesPchForPchTask) { creator.generatePch(std::move(pchTask1)); diff --git a/tests/unit/unittest/pchtaskqueue-test.cpp b/tests/unit/unittest/pchtaskqueue-test.cpp index 3e0bba1bc89..4a8c0862eef 100644 --- a/tests/unit/unittest/pchtaskqueue-test.cpp +++ b/tests/unit/unittest/pchtaskqueue-test.cpp @@ -326,6 +326,22 @@ TEST_F(PchTaskQueue, DeleteProjectPchEntryInDatabaseIfNoPchIsGenerated) tasks.front()(mockPchCreator); } +TEST_F(PchTaskQueue, DeleteProjectPchEntryInDatabaseIfTasksHasNoIncludes) +{ + InSequence s; + MockPchCreator mockPchCreator; + ClangBackEnd::ProjectPartPch projectPartPch{{}, "", 0}; + projectTask1.includes = {}; + auto tasks = queue.createProjectTasks({projectTask1}); + + EXPECT_CALL(mockPrecompiledHeaderStorage, fetchSystemPrecompiledHeaderPath(_)).Times(0); + EXPECT_CALL(mockPchCreator, generatePch(_)).Times(0); + EXPECT_CALL(mockPchCreator, projectPartPch()).Times(0); + EXPECT_CALL(mockPrecompiledHeaderStorage, deleteProjectPrecompiledHeader(Eq(1))); + + tasks.front()(mockPchCreator); +} + TEST_F(PchTaskQueue, CreateSystemTasksSizeEqualsInputSize) { auto tasks = queue.createSystemTasks({systemTask1, systemTask2}); @@ -362,4 +378,20 @@ TEST_F(PchTaskQueue, DeleteSystemPchEntryInDatabaseIfNoPchIsGenerated) tasks.front()(mockPchCreator); } + +TEST_F(PchTaskQueue, DeleteSystemPchEntryInDatabaseIfTasksHasNoIncludes) +{ + InSequence s; + MockPchCreator mockPchCreator; + ClangBackEnd::ProjectPartPch projectPartPch{{}, "", 0}; + systemTask4.includes = {}; + auto tasks = queue.createSystemTasks({systemTask4}); + + EXPECT_CALL(mockPchCreator, generatePch(_)).Times(0); + EXPECT_CALL(mockPchCreator, projectPartPch()).Times(0); + EXPECT_CALL(mockPrecompiledHeaderStorage, + deleteSystemPrecompiledHeaders(UnorderedElementsAre(1, 3))); + + tasks.front()(mockPchCreator); +} } // namespace