diff options
author | Marco Bubke <marco.bubke@qt.io> | 2018-11-12 19:27:51 +0100 |
---|---|---|
committer | Marco Bubke <marco.bubke@qt.io> | 2018-11-20 14:24:03 +0000 |
commit | 64a3a130acc0dc7610168396422f6b8c735f45c8 (patch) | |
tree | efc2f24062d670ef95768280cf6e5b64d58def7a /src/tools/clangpchmanagerbackend | |
parent | e11ff791f0d154087422f138b1c06ef0eb8fb0b4 (diff) | |
download | qt-creator-64a3a130acc0dc7610168396422f6b8c735f45c8.tar.gz |
Clang: Add BuildDependencyCollector
IncludeCollector is renamed to BuildDependencyCollector. It is now
returning a BuildDependency instead of individual getter. The test coverage
is improved too.
Task-number: QTCREATORBUG-21379
Change-Id: Ifc2d1c40c85772cf498c21968de526f4408b6023
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Diffstat (limited to 'src/tools/clangpchmanagerbackend')
15 files changed, 318 insertions, 309 deletions
diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp index f10b6494d8..c3146408f8 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.cpp @@ -27,7 +27,7 @@ #include "builddependenciesstorageinterface.h" #include "modifiedtimecheckerinterface.h" -#include "builddependenciesgeneratorinterface.h" +#include "builddependencygeneratorinterface.h" #include <algorithm> diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h index 00d4101b16..8c22077e81 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h +++ b/src/tools/clangpchmanagerbackend/source/builddependenciesprovider.h @@ -31,14 +31,14 @@ namespace ClangBackEnd { class BuildDependenciesStorageInterface; class ModifiedTimeCheckerInterface; -class BuildDependenciesGeneratorInterface; +class BuildDependencyGeneratorInterface; class BuildDependenciesProvider : public BuildDependenciesProviderInterface { public: BuildDependenciesProvider(BuildDependenciesStorageInterface &buildDependenciesStorage, ModifiedTimeCheckerInterface &modifiedTimeChecker, - BuildDependenciesGeneratorInterface &buildDependenciesGenerator) + BuildDependencyGeneratorInterface &buildDependenciesGenerator) : m_buildDependenciesStorage(buildDependenciesStorage), m_modifiedTimeChecker(modifiedTimeChecker), m_buildDependenciesGenerator(buildDependenciesGenerator) @@ -56,7 +56,7 @@ private: private: BuildDependenciesStorageInterface &m_buildDependenciesStorage; ModifiedTimeCheckerInterface &m_modifiedTimeChecker; - BuildDependenciesGeneratorInterface &m_buildDependenciesGenerator; + BuildDependencyGeneratorInterface &m_buildDependenciesGenerator; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/builddependency.h b/src/tools/clangpchmanagerbackend/source/builddependency.h index 8821b0162c..3faa16c0e3 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependency.h +++ b/src/tools/clangpchmanagerbackend/source/builddependency.h @@ -25,6 +25,8 @@ #pragma once +#include "filestatus.h" +#include "sourcedependency.h" #include "sourceentry.h" #include "usedmacro.h" @@ -33,12 +35,23 @@ namespace ClangBackEnd { class BuildDependency { public: + void clear() + { + includes.clear(); + usedMacros.clear(); + sourceFiles.clear(); + fileStatuses.clear(); + sourceDependencies.clear(); + } + +public: SourceEntries includes; - FilePathIds topIncludeIds; - FilePathIds topsSystemIncludeIds; UsedMacros usedMacros; + FilePathIds sourceFiles; + SourceDependencies sourceDependencies; + FileStatuses fileStatuses; }; using BuildDependencies = std::vector<BuildDependency>; -} +} // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp b/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp new file mode 100644 index 0000000000..4ba3e8c0e6 --- /dev/null +++ b/src/tools/clangpchmanagerbackend/source/builddependencycollector.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "builddependencycollector.h" + +#include "collectbuilddependencytoolaction.h" + +#include <utils/smallstring.h> + +#include <algorithm> + +namespace ClangBackEnd { + +namespace { +FilePathIds operator+(const FilePathIds &first, const FilePathIds &second) +{ + FilePathIds result = first; + + std::copy(second.begin(), second.end(), std::back_inserter(result)); + + return result; +} +} + +BuildDependency BuildDependencyCollector::create(const V2::ProjectPartContainer &projectPart) +{ + addFiles(projectPart.sourcePathIds, projectPart.arguments); + + setExcludedFilePaths( + m_filePathCache.filePaths(projectPart.headerPathIds + projectPart.sourcePathIds)); + + collect(); + + return std::move(m_buildDependency); +} + +void BuildDependencyCollector::collect() +{ + clang::tooling::ClangTool tool = m_clangTool.createTool(); + + auto action = std::make_unique<CollectBuildDependencyToolAction>(m_buildDependency, + m_filePathCache, + m_excludedFilePaths, + m_sourcesManager); + + tool.run(action.get()); +} + +void BuildDependencyCollector::setExcludedFilePaths(ClangBackEnd::FilePaths &&excludedFilePaths) +{ + if (Utils::HostOsInfo::isWindowsHost()) { + m_excludedFilePaths.clear(); + m_excludedFilePaths.reserve(excludedFilePaths.size()); + std::transform(std::make_move_iterator(excludedFilePaths.begin()), + std::make_move_iterator(excludedFilePaths.end()), + std::back_inserter(m_excludedFilePaths), + [](auto &&path) { + path.replace("/", "\\"); + return std::move(path); + }); + } else { + m_excludedFilePaths = std::move(excludedFilePaths); + } +} + +void BuildDependencyCollector::addFiles(const FilePathIds &filePathIds, + const Utils::SmallStringVector &arguments) +{ + m_clangTool.addFiles(m_filePathCache.filePaths(filePathIds), arguments); + m_buildDependency.sourceFiles.insert(m_buildDependency.sourceFiles.end(), + filePathIds.begin(), + filePathIds.end()); +} + +void BuildDependencyCollector::addFile(FilePathId filePathId, + const Utils::SmallStringVector &arguments) +{ + addFiles({filePathId}, arguments); +} + +void BuildDependencyCollector::addFile(FilePath filePath, + const FilePathIds &sourceFileIds, + const Utils::SmallStringVector &arguments) +{ + m_clangTool.addFiles({filePath}, arguments); + m_buildDependency.sourceFiles.insert(m_buildDependency.sourceFiles.end(), + sourceFileIds.begin(), + sourceFileIds.end()); +} + +void BuildDependencyCollector::addUnsavedFiles(const V2::FileContainers &unsavedFiles) +{ + m_clangTool.addUnsavedFiles(unsavedFiles); +} + +void BuildDependencyCollector::clear() +{ + m_clangTool = ClangTool(); + m_buildDependency.clear(); +} + +} // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.h b/src/tools/clangpchmanagerbackend/source/builddependencycollector.h index f97a4901e7..cab749c316 100644 --- a/src/tools/clangpchmanagerbackend/source/includecollector.h +++ b/src/tools/clangpchmanagerbackend/source/builddependencycollector.h @@ -25,27 +25,28 @@ #pragma once +#include "builddependencygeneratorinterface.h" + #include <clangtool.h> -#include <filestatus.h> -#include <sourcedependency.h> #include <sourcesmanager.h> -#include <usedmacro.h> #include <filepathcachingfwd.h> namespace ClangBackEnd { -class IncludeCollector : public ClangTool +class BuildDependencyCollector : public BuildDependencyGeneratorInterface { public: - IncludeCollector(const FilePathCachingInterface &filePathCache) + BuildDependencyCollector(const FilePathCachingInterface &filePathCache) : m_filePathCache(filePathCache) { } + BuildDependency create(const V2::ProjectPartContainer &projectPart) override; + void collect(); - void setExcludedIncludes(Utils::PathStringVector &&excludedIncludes); + void setExcludedFilePaths(ClangBackEnd::FilePaths &&excludedIncludes); void addFiles(const FilePathIds &filePathIds, const Utils::SmallStringVector &arguments); void addFile(FilePathId filePathId, @@ -53,62 +54,43 @@ public: void addFile(FilePath filePath, const FilePathIds &sourceFileIds, const Utils::SmallStringVector &arguments); + void addUnsavedFiles(const V2::FileContainers &unsavedFiles); void clear(); const FileStatuses &fileStatuses() const { - return m_fileStatuses; + return m_buildDependency.fileStatuses; } const FilePathIds &sourceFiles() const { - return m_sourceFiles; + return m_buildDependency.sourceFiles; } const UsedMacros &usedMacros() const { - return m_usedMacros; + return m_buildDependency.usedMacros; } const SourceDependencies &sourceDependencies() const { - return m_sourceDependencies; - } - - FilePathIds takeIncludeIds() - { - std::sort(m_includeIds.begin(), m_includeIds.end()); - - return std::move(m_includeIds); - } - - FilePathIds takeTopIncludeIds() - { - std::sort(m_topIncludeIds.begin(), m_topIncludeIds.end()); - - return std::move(m_topIncludeIds); + return m_buildDependency.sourceDependencies; } - FilePathIds takeTopsSystemIncludeIds() + const SourceEntries &includeIds() { - std::sort(m_topsSystemIncludeIds.begin(), m_topsSystemIncludeIds.end()); + std::sort(m_buildDependency.includes.begin(), m_buildDependency.includes.end()); - return std::move(m_topsSystemIncludeIds); + return std::move(m_buildDependency.includes); } private: ClangTool m_clangTool; - Utils::PathStringVector m_excludedIncludes; - FilePathIds m_includeIds; - FilePathIds m_topIncludeIds; - FilePathIds m_topsSystemIncludeIds; + BuildDependency m_buildDependency; + ClangBackEnd::FilePaths m_excludedFilePaths; Utils::SmallStringVector m_directories; SourcesManager m_sourcesManager; - UsedMacros m_usedMacros; - FilePathIds m_sourceFiles; - SourceDependencies m_sourceDependencies; - FileStatuses m_fileStatuses; const FilePathCachingInterface &m_filePathCache; }; diff --git a/src/tools/clangpchmanagerbackend/source/builddependenciesgeneratorinterface.h b/src/tools/clangpchmanagerbackend/source/builddependencygeneratorinterface.h index f3863d8027..f6e13f3a1a 100644 --- a/src/tools/clangpchmanagerbackend/source/builddependenciesgeneratorinterface.h +++ b/src/tools/clangpchmanagerbackend/source/builddependencygeneratorinterface.h @@ -31,13 +31,13 @@ namespace ClangBackEnd { -class BuildDependenciesGeneratorInterface +class BuildDependencyGeneratorInterface { public: virtual BuildDependency create(const V2::ProjectPartContainer &projectPart) = 0; protected: - ~BuildDependenciesGeneratorInterface() = default; + ~BuildDependencyGeneratorInterface() = default; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri index abdebd22f0..6c45f38ff5 100644 --- a/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri +++ b/src/tools/clangpchmanagerbackend/source/clangpchmanagerbackend-source.pri @@ -5,7 +5,8 @@ SOURCES += \ $$PWD/projectparts.cpp \ $$PWD/projectpartqueue.cpp \ $$PWD/pchtaskgenerator.cpp \ - $$PWD/builddependenciesprovider.cpp + $$PWD/builddependenciesprovider.cpp \ + $$PWD/builddependencycollector.cpp HEADERS += \ $$PWD/pchmanagerserver.h \ @@ -32,20 +33,19 @@ HEADERS += \ $$PWD/builddependency.h \ $$PWD/modifiedtimecheckerinterface.h \ $$PWD/sourceentry.h \ - $$PWD/builddependenciesgeneratorinterface.h \ - $$PWD/builddependenciesstorage.h + $$PWD/builddependenciesstorage.h \ + $$PWD/builddependencycollector.h \ + $$PWD/builddependencygeneratorinterface.h \ + $$PWD/collectbuilddependencytoolaction.h \ + $$PWD/collectbuilddependencyaction.h \ + $$PWD/collectbuilddependencypreprocessorcallbacks.h !isEmpty(LIBTOOLING_LIBS) { SOURCES += \ $$PWD/usedmacrosandsourcescollector.cpp \ - $$PWD/includecollector.cpp \ $$PWD/pchcreator.cpp HEADERS += \ - $$PWD/includecollector.h \ - $$PWD/collectincludestoolaction.h \ - $$PWD/collectincludesaction.h \ - $$PWD/collectincludespreprocessorcallbacks.h \ $$PWD/collectusedmacroactionfactory.h \ $$PWD/collectusedmacrosaction.h \ $$PWD/collectusedmacrosandsourcespreprocessorcallbacks.h \ diff --git a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h b/src/tools/clangpchmanagerbackend/source/collectbuilddependencyaction.h index 17498028b8..ff861f174f 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludesaction.h +++ b/src/tools/clangpchmanagerbackend/source/collectbuilddependencyaction.h @@ -25,7 +25,7 @@ #pragma once -#include <collectincludespreprocessorcallbacks.h> +#include <collectbuilddependencypreprocessorcallbacks.h> #include <filepathcachingfwd.h> #include <filepathid.h> @@ -36,31 +36,19 @@ namespace ClangBackEnd { -class CollectIncludesAction final : public clang::PreprocessOnlyAction +class CollectBuildDependencyAction final : public clang::PreprocessOnlyAction { public: - CollectIncludesAction(FilePathIds &includeIds, - FilePathIds &topIncludeIds, - FilePathIds &topsSystemIncludeIds, + CollectBuildDependencyAction(BuildDependency &buildDependency, const FilePathCachingInterface &filePathCache, std::vector<uint> &excludedIncludeUID, std::vector<uint> &alreadyIncludedFileUIDs, - UsedMacros &usedMacros, - SourcesManager &sourcesManager, - SourceDependencies &sourceDependencies, - FilePathIds &sourceFiles, - FileStatuses &fileStatuses) - : m_includeIds(includeIds), - m_topIncludeIds(topIncludeIds), - m_topsSystemIncludeIds(topsSystemIncludeIds), + SourcesManager &sourcesManager) + : m_buildDependency(buildDependency), m_filePathCache(filePathCache), m_excludedIncludeUID(excludedIncludeUID), m_alreadyIncludedFileUIDs(alreadyIncludedFileUIDs), - m_usedMacros(usedMacros), - m_sourcesManager(sourcesManager), - m_sourceDependencies(sourceDependencies), - m_sourceFiles(sourceFiles), - m_fileStatuses(fileStatuses) + m_sourcesManager(sourcesManager) { } @@ -71,20 +59,14 @@ public: preprocessor.SetSuppressIncludeNotFoundError(true); - auto macroPreprocessorCallbacks = new CollectIncludesPreprocessorCallbacks( - m_includeIds, - m_topIncludeIds, - m_topsSystemIncludeIds, + auto macroPreprocessorCallbacks = new CollectBuildDependencyPreprocessorCallbacks( + m_buildDependency, m_filePathCache, m_excludedIncludeUID, m_alreadyIncludedFileUIDs, compilerInstance.getSourceManager(), - m_usedMacros, m_sourcesManager, - compilerInstance.getPreprocessorPtr(), - m_sourceDependencies, - m_sourceFiles, - m_fileStatuses); + compilerInstance.getPreprocessorPtr()); preprocessor.addPPCallbacks(std::unique_ptr<clang::PPCallbacks>(macroPreprocessorCallbacks)); @@ -100,17 +82,11 @@ public: } private: - FilePathIds &m_includeIds; - FilePathIds &m_topIncludeIds; - FilePathIds &m_topsSystemIncludeIds; + BuildDependency &m_buildDependency; const FilePathCachingInterface &m_filePathCache; std::vector<uint> &m_excludedIncludeUID; std::vector<uint> &m_alreadyIncludedFileUIDs; - UsedMacros &m_usedMacros; SourcesManager &m_sourcesManager; - SourceDependencies &m_sourceDependencies; - FilePathIds &m_sourceFiles; - FileStatuses &m_fileStatuses; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h index 5522fa7bce..664314e309 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludespreprocessorcallbacks.h +++ b/src/tools/clangpchmanagerbackend/source/collectbuilddependencypreprocessorcallbacks.h @@ -25,6 +25,7 @@ #pragma once +#include "builddependency.h" #include "collectmacrospreprocessorcallbacks.h" #include "sourcelocationsutils.h" @@ -33,6 +34,8 @@ #include <utils/smallstringvector.h> +#include <llvm/Support/MemoryBuffer.h> + #include <QFile> #include <QDir> #include <QTemporaryDir> @@ -41,34 +44,26 @@ namespace ClangBackEnd { -class CollectIncludesPreprocessorCallbacks final : public clang::PPCallbacks, +class CollectBuildDependencyPreprocessorCallbacks final : public clang::PPCallbacks, public CollectUsedMacrosAndSourcesPreprocessorCallbacksBase { public: - CollectIncludesPreprocessorCallbacks(FilePathIds &includeIds, - FilePathIds &topIncludeIds, - FilePathIds &topsSystemIncludeIds, + CollectBuildDependencyPreprocessorCallbacks(BuildDependency &buildDependency, const FilePathCachingInterface &filePathCache, const std::vector<uint> &excludedIncludeUID, std::vector<uint> &alreadyIncludedFileUIDs, - const clang::SourceManager &sourceManager, - UsedMacros &usedMacros, + clang::SourceManager &sourceManager, SourcesManager &sourcesManager, - std::shared_ptr<clang::Preprocessor> preprocessor, - SourceDependencies &sourceDependencies, - FilePathIds &sourceFiles, - FileStatuses &fileStatuses) - : CollectUsedMacrosAndSourcesPreprocessorCallbacksBase(usedMacros, + std::shared_ptr<clang::Preprocessor> preprocessor) + : CollectUsedMacrosAndSourcesPreprocessorCallbacksBase(buildDependency.usedMacros, filePathCache, sourceManager, sourcesManager, preprocessor, - sourceDependencies, - sourceFiles, - fileStatuses), - m_includeIds(includeIds), - m_topIncludeIds(topIncludeIds), - m_topsSystemIncludeIds(topsSystemIncludeIds), + buildDependency.sourceDependencies, + buildDependency.sourceFiles, + buildDependency.fileStatuses), + m_buildDependency(buildDependency), m_excludedIncludeUID(excludedIncludeUID), m_alreadyIncludedFileUIDs(alreadyIncludedFileUIDs) {} @@ -90,7 +85,7 @@ public: } void InclusionDirective(clang::SourceLocation hashLocation, - const clang::Token &/*includeToken*/, + const clang::Token & /*includeToken*/, llvm::StringRef /*fileName*/, bool /*isAngled*/, clang::CharSourceRange /*fileNameRange*/, @@ -103,20 +98,30 @@ public: if (!m_skipInclude && file) { addSourceDependency(file, hashLocation); auto fileUID = file->getUID(); - auto sourceFileUID = m_sourceManager->getFileEntryForID(m_sourceManager->getFileID(hashLocation))->getUID(); - if (isNotInExcludedIncludeUID(fileUID)) { - auto notAlreadyIncluded = isNotAlreadyIncluded(fileUID); - if (notAlreadyIncluded.first) { - m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID); - FilePath filePath = filePathFromFile(file); - if (!filePath.empty()) { - FilePathId includeId = m_filePathCache.filePathId(filePath); - m_includeIds.emplace_back(includeId); - if (isSystem(fileType) && !isInSystemHeader(hashLocation)) - m_topsSystemIncludeIds.emplace_back(includeId); - if (isInExcludedIncludeUID(sourceFileUID)) - m_topIncludeIds.emplace_back(includeId); + auto sourceFileUID = m_sourceManager + ->getFileEntryForID(m_sourceManager->getFileID(hashLocation)) + ->getUID(); + auto notAlreadyIncluded = isNotAlreadyIncluded(fileUID); + if (notAlreadyIncluded.first) { + m_alreadyIncludedFileUIDs.insert(notAlreadyIncluded.second, fileUID); + FilePath filePath = filePathFromFile(file); + if (!filePath.empty()) { + FilePathId includeId = m_filePathCache.filePathId(filePath); + + time_t lastModified = file->getModificationTime(); + + SourceType sourceType = SourceType::UserInclude; + if (isSystem(fileType)) { + if (isInSystemHeader(hashLocation)) + sourceType = SourceType::SystemInclude; + else + sourceType = SourceType::TopSystemInclude; + } else if (isNotInExcludedIncludeUID(fileUID) + && isInExcludedIncludeUID(sourceFileUID)) { + sourceType = SourceType::TopInclude; } + + addInclude({includeId, sourceType, lastModified}); } } } @@ -124,19 +129,12 @@ public: m_skipInclude = false; } - bool FileNotFound(clang::StringRef fileNameRef, clang::SmallVectorImpl<char> &recoveryPath) override + bool FileNotFound(clang::StringRef /*fileNameRef*/, + clang::SmallVectorImpl<char> &recoveryPath) override { - QTemporaryDir temporaryDirectory; - temporaryDirectory.setAutoRemove(false); - const QByteArray temporaryDirUtf8 = temporaryDirectory.path().toUtf8(); - - const QString fileName = QString::fromUtf8(fileNameRef.data(), int(fileNameRef.size())); - QString filePath = temporaryDirectory.path() + '/' + fileName; + auto dummyPath = llvm::StringRef("/dummyPath"); - ensureDirectory(temporaryDirectory.path(), fileName); - createFakeFile(filePath); - - recoveryPath.append(temporaryDirUtf8.cbegin(), temporaryDirUtf8.cend()); + recoveryPath.append(std::cbegin(dummyPath), std::cend(dummyPath)); m_skipInclude = true; @@ -189,15 +187,6 @@ public: QDir(directory).mkpath(directoryEntries.join('/')); } - void createFakeFile(const QString &filePath) - { - QFile fakeFile; - fakeFile.setFileName(filePath); - - fakeFile.open(QIODevice::ReadWrite); - fakeFile.close(); - } - bool isNotInExcludedIncludeUID(uint uid) const { return !isInExcludedIncludeUID(uid); @@ -224,10 +213,21 @@ public: return FilePath::fromNativeFilePath(absolutePath(file->getName())); } + void addInclude(SourceEntry sourceEntry) + { + auto &includes = m_buildDependency.includes; + auto found = std::lower_bound(includes.begin(), + includes.end(), + sourceEntry, + [](auto first, auto second) { return first < second; }); + + if (found == includes.end() || *found != sourceEntry) + includes.emplace(found, sourceEntry); + } + private: - FilePathIds &m_includeIds; - FilePathIds &m_topIncludeIds; - FilePathIds &m_topsSystemIncludeIds; + FilePathIds m_containsMissingIncludes; + BuildDependency &m_buildDependency; const std::vector<uint> &m_excludedIncludeUID; std::vector<uint> &m_alreadyIncludedFileUIDs; bool m_skipInclude = false; diff --git a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h b/src/tools/clangpchmanagerbackend/source/collectbuilddependencytoolaction.h index 7820b095fc..4f28d0f7c8 100644 --- a/src/tools/clangpchmanagerbackend/source/collectincludestoolaction.h +++ b/src/tools/clangpchmanagerbackend/source/collectbuilddependencytoolaction.h @@ -25,7 +25,7 @@ #pragma once -#include "collectincludesaction.h" +#include "collectbuilddependencyaction.h" #include <filepathcachingfwd.h> #include <filepathid.h> @@ -34,29 +34,17 @@ namespace ClangBackEnd { -class CollectIncludesToolAction final : public clang::tooling::FrontendActionFactory +class CollectBuildDependencyToolAction final : public clang::tooling::FrontendActionFactory { public: - CollectIncludesToolAction(FilePathIds &includeIds, - FilePathIds &topIncludeIds, - FilePathIds &topsSystemIncludeIds, + CollectBuildDependencyToolAction(BuildDependency &buildDependency, const FilePathCachingInterface &filePathCache, - const Utils::PathStringVector &excludedIncludes, - UsedMacros &usedMacros, - SourcesManager &sourcesManager, - SourceDependencies &sourceDependencies, - FilePathIds &sourceFiles, - FileStatuses &fileStatuses) - : m_includeIds(includeIds), - m_topIncludeIds(topIncludeIds), - m_topsSystemIncludeIds(topsSystemIncludeIds), + const ClangBackEnd::FilePaths &excludedIncludes, + SourcesManager &sourcesManager) + : m_buildDependency(buildDependency), m_filePathCache(filePathCache), - m_excludedIncludes(excludedIncludes), - m_usedMacros(usedMacros), - m_sourcesManager(sourcesManager), - m_sourceDependencies(sourceDependencies), - m_sourceFiles(sourceFiles), - m_fileStatuses(fileStatuses) + m_excludedFilePaths(excludedIncludes), + m_sourcesManager(sourcesManager) {} @@ -76,26 +64,21 @@ public: clang::FrontendAction *create() override { - return new CollectIncludesAction(m_includeIds, - m_topIncludeIds, - m_topsSystemIncludeIds, - m_filePathCache, - m_excludedIncludeUIDs, - m_alreadyIncludedFileUIDs, - m_usedMacros, - m_sourcesManager, - m_sourceDependencies, - m_sourceFiles, - m_fileStatuses); + return new CollectBuildDependencyAction(m_buildDependency, + m_filePathCache, + m_excludedIncludeUIDs, + m_alreadyIncludedFileUIDs, + m_sourcesManager); } std::vector<uint> generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const { std::vector<uint> fileUIDs; - fileUIDs.reserve(m_excludedIncludes.size()); + fileUIDs.reserve(m_excludedFilePaths.size()); - for (const Utils::PathString &filePath : m_excludedIncludes) { - const clang::FileEntry *file = fileManager.getFile({filePath.data(), filePath.size()}, true); + for (const ClangBackEnd::FilePath &filePath : m_excludedFilePaths) { + const clang::FileEntry *file = fileManager.getFile({filePath.data(), filePath.size()}, + true); if (file) fileUIDs.push_back(file->getUID()); @@ -109,16 +92,10 @@ public: private: std::vector<uint> m_alreadyIncludedFileUIDs; std::vector<uint> m_excludedIncludeUIDs; - FilePathIds &m_includeIds; - FilePathIds &m_topIncludeIds; - FilePathIds &m_topsSystemIncludeIds; + BuildDependency &m_buildDependency; const FilePathCachingInterface &m_filePathCache; - const Utils::PathStringVector &m_excludedIncludes; - UsedMacros &m_usedMacros; + const ClangBackEnd::FilePaths &m_excludedFilePaths; SourcesManager &m_sourcesManager; - SourceDependencies &m_sourceDependencies; - FilePathIds &m_sourceFiles; - FileStatuses &m_fileStatuses; }; } // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h b/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h index 9ecd4964a2..90108bd76b 100644 --- a/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h +++ b/src/tools/clangpchmanagerbackend/source/collectusedmacrosandsourcespreprocessorcallbacks.h @@ -102,7 +102,15 @@ public: auto includeFilePathId = filePathId(includeLocation); auto includedFilePathId = filePathId(file); - m_sourceDependencies.emplace_back(includeFilePathId, includedFilePathId); + SourceDependency sourceDependency{includeFilePathId, includedFilePathId}; + + auto found = std::lower_bound(m_sourceDependencies.begin(), + m_sourceDependencies.end(), + sourceDependency, + [](auto first, auto second) { return first < second; }); + + if (found == m_sourceDependencies.end() || *found != sourceDependency) + m_sourceDependencies.emplace(found, sourceDependency); } void mergeUsedMacros() diff --git a/src/tools/clangpchmanagerbackend/source/includecollector.cpp b/src/tools/clangpchmanagerbackend/source/includecollector.cpp deleted file mode 100644 index 6ca7623cc3..0000000000 --- a/src/tools/clangpchmanagerbackend/source/includecollector.cpp +++ /dev/null @@ -1,103 +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. -** -****************************************************************************/ - -#include "includecollector.h" - -#include "collectincludestoolaction.h" - -#include <utils/smallstring.h> - -#include <algorithm> - -namespace ClangBackEnd { - -void IncludeCollector::collect() -{ - clang::tooling::ClangTool tool = m_clangTool.createTool(); - - auto action = std::unique_ptr<CollectIncludesToolAction>( - new CollectIncludesToolAction(m_includeIds, - m_topIncludeIds, - m_topsSystemIncludeIds, - m_filePathCache, - m_excludedIncludes, - m_usedMacros, - m_sourcesManager, - m_sourceDependencies, - m_sourceFiles, - m_fileStatuses)); - - tool.run(action.get()); -} - -void IncludeCollector::setExcludedIncludes(Utils::PathStringVector &&excludedIncludes) -{ -#ifdef _WIN32 - m_excludedIncludes.clear(); - m_excludedIncludes.reserve(excludedIncludes.size()); - std::transform(std::make_move_iterator(excludedIncludes.begin()), - std::make_move_iterator(excludedIncludes.end()), - std::back_inserter(m_excludedIncludes), - [] (Utils::PathString &&path) { - path.replace("/", "\\"); - return std::move(path); - }); - - -#else - m_excludedIncludes = std::move(excludedIncludes); -#endif -} - -void IncludeCollector::addFiles(const FilePathIds &filePathIds, - const Utils::SmallStringVector &arguments) -{ - m_clangTool.addFiles(m_filePathCache.filePaths(filePathIds), arguments); - m_sourceFiles.insert(m_sourceFiles.end(), filePathIds.begin(), filePathIds.end()); -} - -void IncludeCollector::addFile(FilePathId filePathId, const Utils::SmallStringVector &arguments) -{ - addFiles({filePathId}, arguments); -} - -void IncludeCollector::addFile(FilePath filePath, - const FilePathIds &sourceFileIds, - const Utils::SmallStringVector &arguments) -{ - m_clangTool.addFiles({filePath}, arguments); - m_sourceFiles.insert(m_sourceFiles.end(), sourceFileIds.begin(), sourceFileIds.end()); -} - -void IncludeCollector::clear() -{ - m_clangTool = ClangTool(); - m_usedMacros.clear(); - m_sourceFiles.clear(); - m_fileStatuses.clear(); - m_sourceDependencies.clear(); -} - -} // namespace ClangBackEnd diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp index 51e0f129fe..88acf8bb69 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.cpp +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.cpp @@ -26,7 +26,7 @@ #include "pchcreator.h" #include "environment.h" -#include "includecollector.h" +#include "builddependencycollector.h" #include "pchnotcreatederror.h" #include <clangpathwatcherinterface.h> @@ -58,12 +58,12 @@ void append(Target &target, const Source &source) target.push_back(ValueType(std::move(entry))); } -void appendFilePathId(Utils::PathStringVector &target, +void appendFilePathId(ClangBackEnd::FilePaths &target, const ClangBackEnd::FilePathIds &source, const ClangBackEnd::FilePathCachingInterface &filePathCache) { for (FilePathId id : source) - target.emplace_back(filePathCache.filePath(id).path()); + target.emplace_back(filePathCache.filePath(id)); } Utils::PathStringVector generatedFilePaths(const V2::FileContainers &generaredFiles) @@ -190,23 +190,23 @@ Utils::PathStringVector PchCreator::generateProjectPartHeaders( namespace { -std::size_t sizeOfContent(const Utils::PathStringVector &paths) +std::size_t sizeOfContent(const ClangBackEnd::FilePaths &paths) { return std::accumulate(paths.begin(), paths.end(), std::size_t(0), - [] (std::size_t size, const Utils::PathString &path) { + [] (std::size_t size, const auto &path) { const char includeTemplate[] = "#include \"\"\n"; return size + path.size() + sizeof(includeTemplate); }); } -Utils::SmallString concatContent(const Utils::PathStringVector &paths, std::size_t size) +Utils::SmallString concatContent(const ClangBackEnd::FilePaths &paths, std::size_t size) { Utils::SmallString content; content.reserve(size); - for (const Utils::PathString &path : paths) { + for (const ClangBackEnd::FilePath &path : paths) { content += "#include \""; content += path; content += "\"\n"; @@ -220,15 +220,15 @@ Utils::SmallString concatContent(const Utils::PathStringVector &paths, std::size Utils::SmallString PchCreator::generateProjectPartSourcesContent( const V2::ProjectPartContainer &projectPart) const { - Utils::PathStringVector paths = generateProjectPartSourcePaths(projectPart); + ClangBackEnd::FilePaths paths = generateProjectPartSourcePaths(projectPart); return concatContent(paths, sizeOfContent(paths)); } -Utils::PathStringVector PchCreator::generateProjectPartSourcePaths( - const V2::ProjectPartContainer &projectPart) const +ClangBackEnd::FilePaths PchCreator::generateProjectPartSourcePaths( + const V2::ProjectPartContainer &projectPart) const { - Utils::PathStringVector includeAndSources; + ClangBackEnd::FilePaths includeAndSources; includeAndSources.reserve(projectPart.sourcePathIds.size()); appendFilePathId(includeAndSources, projectPart.sourcePathIds, m_filePathCache); @@ -236,7 +236,7 @@ Utils::PathStringVector PchCreator::generateProjectPartSourcePaths( return includeAndSources; } -PchCreatorIncludes PchCreator::generateProjectPartPchIncludes( +SourceEntries PchCreator::generateProjectPartPchIncludes( const V2::ProjectPartContainer &projectPart) const { Utils::SmallString jointedFileContent = generateProjectPartSourcesContent(projectPart); @@ -245,9 +245,9 @@ PchCreatorIncludes PchCreator::generateProjectPartPchIncludes( Utils::SmallStringVector arguments = generateProjectPartCommandLine(projectPart); FilePath filePath{Utils::PathString(jointedFilePath)}; - IncludeCollector collector(m_filePathCache); + BuildDependencyCollector collector(m_filePathCache); - collector.setExcludedIncludes(generateProjectPartSourcePaths(projectPart)); + collector.setExcludedFilePaths(generateProjectPartSourcePaths(projectPart)); collector.addFile(filePath, projectPart.sourcePathIds, arguments); @@ -257,7 +257,7 @@ PchCreatorIncludes PchCreator::generateProjectPartPchIncludes( jointFile->remove(); - return {collector.takeIncludeIds(), collector.takeTopIncludeIds(), collector.takeTopsSystemIncludeIds()}; + return collector.includeIds(); } Utils::SmallString PchCreator::generateProjectPathPchHeaderFilePath( @@ -309,7 +309,7 @@ IdPaths PchCreator::generateProjectPartPch(const V2::ProjectPartContainer &proje { long long lastModified = QDateTime::currentSecsSinceEpoch(); auto includes = generateProjectPartPchIncludes(projectPart); - auto content = generatePchIncludeFileContent(includes.topIncludeIds); + auto content = generatePchIncludeFileContent(topIncludeIds(includes)); auto pchIncludeFilePath = generateProjectPathPchHeaderFilePath(projectPart); auto pchFilePath = generateProjectPartPchFilePath(projectPart); generateFileWithContent(pchIncludeFilePath, content); @@ -323,7 +323,7 @@ IdPaths PchCreator::generateProjectPartPch(const V2::ProjectPartContainer &proje m_projectPartPch.lastModified = lastModified; } - return {projectPart.projectPartId.clone(), std::move(includes.includeIds)}; + return {projectPart.projectPartId.clone(), allIncludeIds(includes)}; } void PchCreator::generatePch(const V2::ProjectPartContainer &projectPart) @@ -392,6 +392,32 @@ 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::TopInclude) + 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); diff --git a/src/tools/clangpchmanagerbackend/source/pchcreator.h b/src/tools/clangpchmanagerbackend/source/pchcreator.h index 7f95b074cb..34461dc16b 100644 --- a/src/tools/clangpchmanagerbackend/source/pchcreator.h +++ b/src/tools/clangpchmanagerbackend/source/pchcreator.h @@ -28,6 +28,7 @@ #include "pchcreatorinterface.h" #include "idpaths.h" +#include "sourceentry.h" #include <filepathcaching.h> #include <projectpartpch.h> @@ -93,9 +94,9 @@ public: const V2::ProjectPartContainer &projectPart) const; Utils::SmallString generateProjectPartSourcesContent( const V2::ProjectPartContainer &projectPart) const; - Utils::PathStringVector generateProjectPartSourcePaths( + ClangBackEnd::FilePaths generateProjectPartSourcePaths( const V2::ProjectPartContainer &projectPart) const; - PchCreatorIncludes generateProjectPartPchIncludes( + SourceEntries generateProjectPartPchIncludes( const V2::ProjectPartContainer &projectPart) const; Utils::SmallString generateProjectPathPchHeaderFilePath( const V2::ProjectPartContainer &projectPart) const; @@ -113,6 +114,9 @@ public: const Utils::SmallString &filePath, const Utils::SmallString &content); + static FilePathIds topIncludeIds(const SourceEntries &includes); + static FilePathIds allIncludeIds(const SourceEntries &includes); + private: static QByteArray projectPartHash(const V2::ProjectPartContainer &projectPart); diff --git a/src/tools/clangpchmanagerbackend/source/sourceentry.h b/src/tools/clangpchmanagerbackend/source/sourceentry.h index 2a5e4ba06f..6859e838ad 100644 --- a/src/tools/clangpchmanagerbackend/source/sourceentry.h +++ b/src/tools/clangpchmanagerbackend/source/sourceentry.h @@ -33,9 +33,10 @@ namespace ClangBackEnd { enum class SourceType : unsigned char { - Any, TopInclude, - TopSystemInclude + TopSystemInclude, + UserInclude, + SystemInclude }; class TimeStamp @@ -62,7 +63,6 @@ public: : lastModified(lastModified), sourceId(sourceId), sourceType(static_cast<SourceType>(sourceType)) - {} SourceEntry(FilePathId sourceId, SourceType sourceType, TimeStamp lastModified) @@ -85,10 +85,12 @@ public: && first.lastModified == second.lastModified ; } + friend bool operator!=(SourceEntry first, SourceEntry second) { return !(first == second); } + public: TimeStamp lastModified; FilePathId sourceId; - SourceType sourceType = SourceType::Any; + SourceType sourceType = SourceType::UserInclude; }; using SourceEntries = std::vector<SourceEntry>; |