diff --git a/src/lib/project/Project.cpp b/src/lib/project/Project.cpp index 4855b1c1..6bd9ed68 100644 --- a/src/lib/project/Project.cpp +++ b/src/lib/project/Project.cpp @@ -549,7 +549,7 @@ void Project::buildIndex(RefreshInfo info, std::shared_ptr dialogVie { if (sourceGroup->getStatus() == SOURCE_GROUP_STATUS_ENABLED) { - preIndexTasks->addTask(sourceGroup->getPreIndexTask(dialogView)); + preIndexTasks->addTask(sourceGroup->getPreIndexTask(storageProvider, dialogView)); } } diff --git a/src/lib/project/SourceGroup.cpp b/src/lib/project/SourceGroup.cpp index bf6216fa..ed80ae70 100644 --- a/src/lib/project/SourceGroup.cpp +++ b/src/lib/project/SourceGroup.cpp @@ -12,7 +12,8 @@ std::shared_ptr SourceGroup::getIndexerCommandProvider(c return std::make_shared(getIndexerCommands(filesToIndex)); } -std::shared_ptr SourceGroup::getPreIndexTask(std::shared_ptr dialogView) const +std::shared_ptr SourceGroup::getPreIndexTask( + std::shared_ptr storageProvider, std::shared_ptr dialogView) const { return std::make_shared([]() {}); } diff --git a/src/lib/project/SourceGroup.h b/src/lib/project/SourceGroup.h index 8c06bfc3..49e97b02 100644 --- a/src/lib/project/SourceGroup.h +++ b/src/lib/project/SourceGroup.h @@ -15,6 +15,7 @@ class FilePathFilter; class IndexerCommand; class IndexerCommandProvider; class SourceGroupSettings; +class StorageProvider; class Task; class SourceGroup @@ -29,7 +30,8 @@ public: virtual std::set getAllSourceFilePaths() const = 0; virtual std::shared_ptr getIndexerCommandProvider(const std::set& filesToIndex) const; virtual std::vector> getIndexerCommands(const std::set& filesToIndex) const = 0; - virtual std::shared_ptr getPreIndexTask(std::shared_ptr dialogView) const; + virtual std::shared_ptr getPreIndexTask( + std::shared_ptr storageProvider, std::shared_ptr dialogView) const; SourceGroupType getType() const; LanguageType getLanguage() const; diff --git a/src/lib_cxx/data/parser/cxx/GeneratePCHAction.cpp b/src/lib_cxx/data/parser/cxx/GeneratePCHAction.cpp index 6e9b170b..9f9ddcbf 100644 --- a/src/lib_cxx/data/parser/cxx/GeneratePCHAction.cpp +++ b/src/lib_cxx/data/parser/cxx/GeneratePCHAction.cpp @@ -1,8 +1,18 @@ #include "GeneratePCHAction.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Serialization/ASTWriter.h" -#include "clang/Frontend/MultiplexConsumer.h" +#include +#include +#include + +#include "PreprocessorCallbacks.h" + +GeneratePCHAction::GeneratePCHAction( + std::shared_ptr client, + std::shared_ptr canonicalFilePathCache +) + : m_client(client) + , m_canonicalFilePathCache(canonicalFilePathCache) +{} bool GeneratePCHAction::shouldEraseOutputFiles() { @@ -37,3 +47,12 @@ std::unique_ptr GeneratePCHAction::CreateASTConsumer(clang:: return llvm::make_unique(std::move(Consumers)); } + +bool GeneratePCHAction::BeginSourceFileAction(clang::CompilerInstance& compiler) +{ + clang::Preprocessor& preprocessor = compiler.getPreprocessor(); + preprocessor.addPPCallbacks(llvm::make_unique( + compiler.getSourceManager(), m_client, m_canonicalFilePathCache + )); + return true; +} diff --git a/src/lib_cxx/data/parser/cxx/GeneratePCHAction.h b/src/lib_cxx/data/parser/cxx/GeneratePCHAction.h index 121e806e..20205c86 100644 --- a/src/lib_cxx/data/parser/cxx/GeneratePCHAction.h +++ b/src/lib_cxx/data/parser/cxx/GeneratePCHAction.h @@ -3,14 +3,30 @@ #include "clang/Frontend/FrontendActions.h" -class GeneratePCHAction : public clang::GeneratePCHAction +class ParserClient; +class CanonicalFilePathCache; + +class GeneratePCHAction + : public clang::GeneratePCHAction { +public: + explicit GeneratePCHAction( + std::shared_ptr client, + std::shared_ptr canonicalFilePathCache + ); + protected: // this method has been overridden to prevent erasing output file independently of provided flags bool shouldEraseOutputFiles() override; // this method has been overridden to always set "AllowASTWithErrors" of the PCHGenerator to "true" std::unique_ptr CreateASTConsumer(clang::CompilerInstance &CI, llvm::StringRef InFile) override; + + bool BeginSourceFileAction(clang::CompilerInstance& compiler) override; + +private: + std::shared_ptr m_client; + std::shared_ptr m_canonicalFilePathCache; }; #endif // GENERATE_PCH_ACTION_H diff --git a/src/lib_cxx/project/SourceGroupCxxCdb.cpp b/src/lib_cxx/project/SourceGroupCxxCdb.cpp index 6bb0b9ac..e154bb9b 100644 --- a/src/lib_cxx/project/SourceGroupCxxCdb.cpp +++ b/src/lib_cxx/project/SourceGroupCxxCdb.cpp @@ -151,7 +151,8 @@ std::vector> SourceGroupCxxCdb::getIndexerComman return getIndexerCommandProvider(filesToIndex)->consumeAllCommands(); } -std::shared_ptr SourceGroupCxxCdb::getPreIndexTask(std::shared_ptr dialogView) const +std::shared_ptr SourceGroupCxxCdb::getPreIndexTask( + std::shared_ptr storageProvider, std::shared_ptr dialogView) const { if (m_settings->getPchInputFilePath().empty()) { @@ -213,7 +214,7 @@ std::shared_ptr SourceGroupCxxCdb::getPreIndexTask(std::shared_ptrgetPchFlags()); - return utility::createBuildPchTask(m_settings.get(), compilerFlags, dialogView); + return utility::createBuildPchTask(m_settings.get(), compilerFlags, storageProvider, dialogView); } std::shared_ptr SourceGroupCxxCdb::getSourceGroupSettings() diff --git a/src/lib_cxx/project/SourceGroupCxxCdb.h b/src/lib_cxx/project/SourceGroupCxxCdb.h index 3f15e8f1..ce829c7e 100644 --- a/src/lib_cxx/project/SourceGroupCxxCdb.h +++ b/src/lib_cxx/project/SourceGroupCxxCdb.h @@ -27,7 +27,8 @@ public: std::set getAllSourceFilePaths(std::shared_ptr cdb) const; std::shared_ptr getIndexerCommandProvider(const std::set& filesToIndex) const override; std::vector> getIndexerCommands(const std::set& filesToIndex) const override; - std::shared_ptr getPreIndexTask(std::shared_ptr dialogView) const override; + std::shared_ptr getPreIndexTask( + std::shared_ptr storageProvider, std::shared_ptr dialogView) const override; private: std::shared_ptr getSourceGroupSettings() override; diff --git a/src/lib_cxx/project/SourceGroupCxxEmpty.cpp b/src/lib_cxx/project/SourceGroupCxxEmpty.cpp index 2766282a..949e82a6 100644 --- a/src/lib_cxx/project/SourceGroupCxxEmpty.cpp +++ b/src/lib_cxx/project/SourceGroupCxxEmpty.cpp @@ -112,7 +112,8 @@ std::vector> SourceGroupCxxEmpty::getIndexerComm return getIndexerCommandProvider(filesToIndex)->consumeAllCommands(); } -std::shared_ptr SourceGroupCxxEmpty::getPreIndexTask(std::shared_ptr dialogView) const +std::shared_ptr SourceGroupCxxEmpty::getPreIndexTask( + std::shared_ptr storageProvider, std::shared_ptr dialogView) const { const SourceGroupSettingsWithCxxPchOptions* pchSettings = dynamic_cast(m_settings.get()); @@ -134,7 +135,7 @@ std::shared_ptr SourceGroupCxxEmpty::getPreIndexTask(std::shared_ptrgetPchFlags()); } - return utility::createBuildPchTask(m_settings.get(), compilerFlags, dialogView); + return utility::createBuildPchTask(m_settings.get(), compilerFlags, storageProvider, dialogView); } std::shared_ptr SourceGroupCxxEmpty::getSourceGroupSettings() diff --git a/src/lib_cxx/project/SourceGroupCxxEmpty.h b/src/lib_cxx/project/SourceGroupCxxEmpty.h index 0daecd01..4c6a0e3e 100644 --- a/src/lib_cxx/project/SourceGroupCxxEmpty.h +++ b/src/lib_cxx/project/SourceGroupCxxEmpty.h @@ -17,7 +17,8 @@ public: std::set getAllSourceFilePaths() const override; std::shared_ptr getIndexerCommandProvider(const std::set& filesToIndex) const override; std::vector> getIndexerCommands(const std::set& filesToIndex) const override; - std::shared_ptr getPreIndexTask(std::shared_ptr dialogView) const override; + std::shared_ptr getPreIndexTask( + std::shared_ptr storageProvider, std::shared_ptr dialogView) const override; private: std::shared_ptr getSourceGroupSettings() override; diff --git a/src/lib_cxx/project/utilitySourceGroupCxx.cpp b/src/lib_cxx/project/utilitySourceGroupCxx.cpp index e0e262b4..ef218682 100644 --- a/src/lib_cxx/project/utilitySourceGroupCxx.cpp +++ b/src/lib_cxx/project/utilitySourceGroupCxx.cpp @@ -1,23 +1,31 @@ #include "utilitySourceGroupCxx.h" +#include "CanonicalFilePathCache.h" #include "CxxCompilationDatabaseSingle.h" +#include "CxxDiagnosticConsumer.h" #include "CxxParser.h" #include "DialogView.h" +#include "FilePathFilter.h" +#include "FileRegister.h" #include "FileSystem.h" #include "GeneratePCHAction.h" #include "logging.h" +#include "ParserClientImpl.h" #include "SingleFrontendActionFactory.h" #include "SourceGroupSettingsCxx.h" #include "SourceGroupSettingsWithCxxPchOptions.h" +#include "StorageProvider.h" #include "TaskLambda.h" #include "utility.h" namespace utility { std::shared_ptr createBuildPchTask( - const SourceGroupSettingsCxx* settings, std::vector compilerFlags, std::shared_ptr dialogView) + const SourceGroupSettingsCxx* settings, std::vector compilerFlags, + std::shared_ptr storageProvider, std::shared_ptr dialogView) { - const SourceGroupSettingsWithCxxPchOptions* pchSettings = dynamic_cast(settings); + const SourceGroupSettingsWithCxxPchOptions* pchSettings = + dynamic_cast(settings); if (!pchSettings) { return std::make_shared([](){}); @@ -37,7 +45,8 @@ namespace utility return std::make_shared([]() {}); } - const FilePath pchOutputFilePath = pchDependenciesDirectoryPath.getConcatenated(pchInputFilePath.fileName()).replaceExtension(L"pch"); + const FilePath pchOutputFilePath = + pchDependenciesDirectoryPath.getConcatenated(pchInputFilePath.fileName()).replaceExtension(L"pch"); compilerFlags.push_back(pchInputFilePath.wstr()); compilerFlags.push_back(L"-emit-pch"); @@ -45,7 +54,7 @@ namespace utility compilerFlags.push_back(pchOutputFilePath.wstr()); return std::make_shared( - [dialogView, pchInputFilePath, pchOutputFilePath, compilerFlags]() + [dialogView, storageProvider, pchInputFilePath, pchOutputFilePath, compilerFlags]() { dialogView->showUnknownProgressDialog(L"Preparing Indexing", L"Processing Precompiled Headers"); LOG_INFO( @@ -60,24 +69,43 @@ namespace utility FileSystem::createDirectory(pchOutputFilePath.getParentDirectory()); } + std::shared_ptr storage = std::make_shared(); + std::shared_ptr client = std::make_shared(storage.get()); + + std::shared_ptr fileRegister = std::make_shared( + pchInputFilePath, std::set{ pchInputFilePath }, std::set{}); + + std::shared_ptr canonicalFilePathCache = + std::make_shared(fileRegister); + clang::tooling::CompileCommand pchCommand; pchCommand.Filename = utility::encodeToUtf8(pchInputFilePath.fileName()); pchCommand.Directory = pchOutputFilePath.getParentDirectory().str(); // DON'T use "-fsyntax-only" here because it will cause the output file to be erased - pchCommand.CommandLine = utility::concat({ "clang-tool" }, CxxParser::getCommandlineArgumentsEssential(compilerFlags)); + pchCommand.CommandLine = + utility::concat({ "clang-tool" }, CxxParser::getCommandlineArgumentsEssential(compilerFlags)); CxxCompilationDatabaseSingle compilationDatabase(pchCommand); - clang::tooling::ClangTool tool(compilationDatabase, std::vector(1, utility::encodeToUtf8(pchInputFilePath.wstr()))); - GeneratePCHAction* action = new GeneratePCHAction(); + clang::tooling::ClangTool tool(compilationDatabase, { utility::encodeToUtf8(pchInputFilePath.wstr()) }); + GeneratePCHAction* action = new GeneratePCHAction(client, canonicalFilePathCache); + + llvm::IntrusiveRefCntPtr options = new clang::DiagnosticOptions(); + CxxDiagnosticConsumer diagnostics( + llvm::errs(), &*options, client, canonicalFilePathCache, pchInputFilePath, true); + + tool.setDiagnosticConsumer(&diagnostics); tool.clearArgumentsAdjusters(); tool.run(new SingleFrontendActionFactory(action)); + + storageProvider->insert(storage); } ); } std::vector getIncludePchFlags(const SourceGroupSettingsCxx* settings) { - const SourceGroupSettingsWithCxxPchOptions* pchSettings = dynamic_cast(settings); + const SourceGroupSettingsWithCxxPchOptions* pchSettings = + dynamic_cast(settings); if (pchSettings) { const FilePath pchInputFilePath = pchSettings->getPchInputFilePathExpandedAndAbsolute(); @@ -85,7 +113,8 @@ namespace utility if (!pchInputFilePath.empty() && !pchDependenciesDirectoryPath.empty()) { - const FilePath pchOutputFilePath = pchDependenciesDirectoryPath.getConcatenated(pchInputFilePath.fileName()).replaceExtension(L"pch"); + const FilePath pchOutputFilePath = + pchDependenciesDirectoryPath.getConcatenated(pchInputFilePath.fileName()).replaceExtension(L"pch"); return { L"-fallow-pch-with-compiler-errors", L"-include-pch", diff --git a/src/lib_cxx/project/utilitySourceGroupCxx.h b/src/lib_cxx/project/utilitySourceGroupCxx.h index d7f0366f..834c7f08 100644 --- a/src/lib_cxx/project/utilitySourceGroupCxx.h +++ b/src/lib_cxx/project/utilitySourceGroupCxx.h @@ -7,12 +7,14 @@ class DialogView; class SourceGroupSettingsCxx; +class StorageProvider; class Task; namespace utility { std::shared_ptr createBuildPchTask( - const SourceGroupSettingsCxx* settings, std::vector compilerFlags, std::shared_ptr dialogView); + const SourceGroupSettingsCxx* settings, std::vector compilerFlags, + std::shared_ptr storageProvider, std::shared_ptr dialogView); std::vector getIncludePchFlags(const SourceGroupSettingsCxx* settings); }