[clang-tools-extra] [clangd] [C++20] [Modules] Introduce initial support for C++20 Modules (PR #66462)

Sam McCall via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 26 03:59:00 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(
----------------
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


More information about the cfe-commits mailing list