[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Tue Oct 31 00:32:33 PDT 2023
================
@@ -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(
----------------
ChuanqiXu9 wrote:
Done. Originally I just felt it was simpler. And now I feel passing `-fmodule-file=<module-name>=<module-file>` looks more neat indeed.
https://github.com/llvm/llvm-project/pull/66462
More information about the cfe-commits
mailing list