================ @@ -0,0 +1,278 @@ +//===----------------- PrerequisiteModules.cpp -----------------------*- +//C++-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "PrerequisiteModules.h" +#include "ProjectModules.h" +#include "support/Logger.h" + +#include "clang/Frontend/FrontendAction.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Serialization/ASTReader.h" + +namespace clang { +namespace clangd { + +namespace { +llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) { + llvm::SmallString<128> AbsolutePath; + if (llvm::sys::path::is_absolute(Cmd.Filename)) { + AbsolutePath = Cmd.Filename; + } else { + AbsolutePath = Cmd.Directory; + llvm::sys::path::append(AbsolutePath, Cmd.Filename); + llvm::sys::path::remove_dots(AbsolutePath, true); + } + return AbsolutePath; +} +} // namespace + +PrerequisiteModules::PrerequisiteModules(PathRef MainFile, + const GlobalCompilationDatabase &CDB) { + std::optional<ProjectInfo> PI = CDB.getProjectInfo(MainFile); + if (!PI) + return; + + llvm::SmallString<128> Result(PI->SourceRoot); + llvm::sys::path::append(Result, ".cache"); + llvm::sys::path::append(Result, "clangd"); + llvm::sys::path::append(Result, "module_files"); + llvm::sys::fs::create_directories(Result, /*IgnoreExisting=*/true); + + llvm::sys::path::append(Result, llvm::sys::path::filename(MainFile)); + llvm::sys::fs::createUniqueDirectory(Result, UniqueModuleFilesPathPrefix); + + log("Initialized module files to {0}", UniqueModuleFilesPathPrefix.str()); +} + +PrerequisiteModules::~PrerequisiteModules() { + DependentModuleNames.clear(); + + if (UniqueModuleFilesPathPrefix.empty()) + return; + + llvm::sys::fs::remove_directories(UniqueModuleFilesPathPrefix); + UniqueModuleFilesPathPrefix.clear(); +} + +llvm::SmallString<256> +PrerequisiteModules::getModuleFilePath(StringRef ModuleName) const { + llvm::SmallString<256> ModuleFilePath; + + ModuleFilePath = UniqueModuleFilesPathPrefix; + auto [PrimaryModuleName, PartitionName] = ModuleName.split(':'); + llvm::sys::path::append(ModuleFilePath, PrimaryModuleName); + if (!PartitionName.empty()) { + ModuleFilePath.append("-"); + ModuleFilePath.append(PartitionName); + } + ModuleFilePath.append(".pcm"); + + return ModuleFilePath; +} + +bool PrerequisiteModules::isModuleUnitBuilt(StringRef ModuleName) const { + if (!DependentModuleNames.count(ModuleName)) + return false; + + auto BMIPath = getModuleFilePath(ModuleName); + if (llvm::sys::fs::exists(BMIPath)) + return true; + + DependentModuleNames.erase(ModuleName); + return false; +} + +void PrerequisiteModules::adjustHeaderSearchOptions( + HeaderSearchOptions &Options) const { + if (!IsInited()) + return; + + Options.PrebuiltModulePaths.insert(Options.PrebuiltModulePaths.begin(), + UniqueModuleFilesPathPrefix.str().str()); + + for (auto Iter = Options.PrebuiltModuleFiles.begin(); + Iter != Options.PrebuiltModuleFiles.end();) { + if (isModuleUnitBuilt(Iter->first)) { + Iter = Options.PrebuiltModuleFiles.erase(Iter); + continue; + } + + Iter++; + } +} + +void PrerequisiteModules::adjustCompileCommands( + tooling::CompileCommand &Cmd) const { + if (!IsInited()) + return; + + std::vector<std::string> CommandLine(std::move(Cmd.CommandLine)); + + Cmd.CommandLine.emplace_back(CommandLine[0]); + Cmd.CommandLine.emplace_back( ---------------- sam-mccall wrote:
why do we need this line? we should be passing all paths explicitly with -fmodule-file=, no? https://github.com/llvm/llvm-project/pull/66462 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits