[clang-tools-extra] [llvm] [clangd] Normalize path identity across file-tracking boundaries (PR #221921)

via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 8 01:46:37 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clangd

@llvm/pr-subscribers-clang-tools-extra

Author: Daedie-git

<details>
<summary>Changes</summary>

## Summary

Normalize file identity across clangd's document tracking, scheduling, caches, edits, and indexing. Absolute Windows drive-letter and separator aliases refer to the same file, while filename case is preserved so case-sensitive directories do not lose distinct files.

- Introduce explicit `Path`, `PathRef`, and `PathMap` boundaries while preserving original spellings.
- Provide path-aware dirty-header snapshots with stable file IDs and correct working-directory resolution.
- Keep custom URI keys opaque and avoid allocations for common index-coverage lookups.
- Add regression coverage and update CMake/GN integration and cache memory accounting.

## Validation

Windows Release build with assertions: `check-clangd` — **1,509 passed, 22 unsupported**.

Linux/macOS and GN builds have not been run locally.

---

Patch is 267.50 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/221921.diff


81 Files Affected:

- (modified) clang-tools-extra/clangd/ASTSignals.cpp (+1-1) 
- (modified) clang-tools-extra/clangd/CMakeLists.txt (+1) 
- (modified) clang-tools-extra/clangd/ClangdLSPServer.cpp (+13-12) 
- (modified) clang-tools-extra/clangd/ClangdLSPServer.h (+2-3) 
- (modified) clang-tools-extra/clangd/ClangdServer.cpp (+42-39) 
- (modified) clang-tools-extra/clangd/ClangdServer.h (+1-1) 
- (modified) clang-tools-extra/clangd/CodeComplete.cpp (+18-16) 
- (modified) clang-tools-extra/clangd/ConfigCompile.cpp (+6-3) 
- (modified) clang-tools-extra/clangd/ConfigProvider.cpp (+5-4) 
- (modified) clang-tools-extra/clangd/DraftStore.cpp (+256-23) 
- (modified) clang-tools-extra/clangd/DraftStore.h (+4-2) 
- (modified) clang-tools-extra/clangd/FS.cpp (+15-19) 
- (modified) clang-tools-extra/clangd/FS.h (+2-9) 
- (modified) clang-tools-extra/clangd/FileDistance.cpp (+4) 
- (modified) clang-tools-extra/clangd/GlobalCompilationDatabase.cpp (+30-29) 
- (modified) clang-tools-extra/clangd/GlobalCompilationDatabase.h (+1-1) 
- (modified) clang-tools-extra/clangd/HeaderSourceSwitch.cpp (+12-12) 
- (modified) clang-tools-extra/clangd/Headers.cpp (+5-4) 
- (modified) clang-tools-extra/clangd/Hover.cpp (+1-1) 
- (modified) clang-tools-extra/clangd/IncludeCleaner.cpp (+8-8) 
- (modified) clang-tools-extra/clangd/ModulesBuilder.cpp (+29-30) 
- (modified) clang-tools-extra/clangd/ParsedAST.cpp (+3-2) 
- (modified) clang-tools-extra/clangd/Preamble.cpp (+4-4) 
- (modified) clang-tools-extra/clangd/ProjectModules.cpp (+14-14) 
- (modified) clang-tools-extra/clangd/Protocol.cpp (+5-5) 
- (modified) clang-tools-extra/clangd/Protocol.h (+4-4) 
- (modified) clang-tools-extra/clangd/SourceCode.h (+3-2) 
- (modified) clang-tools-extra/clangd/SystemIncludeExtractor.cpp (+2-1) 
- (modified) clang-tools-extra/clangd/TUScheduler.cpp (+84-64) 
- (modified) clang-tools-extra/clangd/TUScheduler.h (+1-1) 
- (modified) clang-tools-extra/clangd/TidyProvider.cpp (+7-7) 
- (modified) clang-tools-extra/clangd/URI.h (+2) 
- (modified) clang-tools-extra/clangd/XRefs.cpp (+17-15) 
- (modified) clang-tools-extra/clangd/index/Background.cpp (+31-23) 
- (modified) clang-tools-extra/clangd/index/Background.h (+3-2) 
- (modified) clang-tools-extra/clangd/index/BackgroundIndexLoader.cpp (+19-18) 
- (modified) clang-tools-extra/clangd/index/BackgroundIndexLoader.h (+1-1) 
- (modified) clang-tools-extra/clangd/index/BackgroundIndexStorage.cpp (+9-7) 
- (modified) clang-tools-extra/clangd/index/FileIndex.cpp (+59-36) 
- (modified) clang-tools-extra/clangd/index/FileIndex.h (+13-8) 
- (modified) clang-tools-extra/clangd/index/MemIndex.cpp (+7-2) 
- (modified) clang-tools-extra/clangd/index/MemIndex.h (+8-3) 
- (added) clang-tools-extra/clangd/index/PathIdentity.cpp (+94) 
- (added) clang-tools-extra/clangd/index/PathIdentity.h (+93) 
- (modified) clang-tools-extra/clangd/index/dex/Dex.cpp (+6-1) 
- (modified) clang-tools-extra/clangd/index/dex/Dex.h (+9-4) 
- (modified) clang-tools-extra/clangd/refactor/Rename.cpp (+11-10) 
- (modified) clang-tools-extra/clangd/refactor/Tweak.cpp (+1-1) 
- (modified) clang-tools-extra/clangd/refactor/Tweak.h (+2-1) 
- (modified) clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp (+3-2) 
- (modified) clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp (+17-14) 
- (modified) clang-tools-extra/clangd/support/FileCache.cpp (+5-5) 
- (modified) clang-tools-extra/clangd/support/FileCache.h (+1-1) 
- (modified) clang-tools-extra/clangd/support/Path.cpp (+232-27) 
- (modified) clang-tools-extra/clangd/support/Path.h (+328-25) 
- (modified) clang-tools-extra/clangd/support/ThreadsafeFS.cpp (+1-1) 
- (modified) clang-tools-extra/clangd/test/memory_tree.test (-1) 
- (modified) clang-tools-extra/clangd/tool/ClangdMain.cpp (+8-8) 
- (modified) clang-tools-extra/clangd/unittests/ASTTests.cpp (+1-1) 
- (modified) clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp (+82-25) 
- (modified) clang-tools-extra/clangd/unittests/ClangdTests.cpp (+8-8) 
- (modified) clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp (+1-1) 
- (modified) clang-tools-extra/clangd/unittests/CompileCommandsTests.cpp (+15) 
- (modified) clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp (+15) 
- (modified) clang-tools-extra/clangd/unittests/DexTests.cpp (+14) 
- (modified) clang-tools-extra/clangd/unittests/DraftStoreTests.cpp (+346) 
- (modified) clang-tools-extra/clangd/unittests/FSTests.cpp (+39) 
- (modified) clang-tools-extra/clangd/unittests/FileIndexTests.cpp (+166) 
- (modified) clang-tools-extra/clangd/unittests/GlobalCompilationDatabaseTests.cpp (+19-6) 
- (modified) clang-tools-extra/clangd/unittests/HeaderSourceSwitchTests.cpp (+10-4) 
- (modified) clang-tools-extra/clangd/unittests/HeadersTests.cpp (+1-1) 
- (modified) clang-tools-extra/clangd/unittests/IndexTests.cpp (+42) 
- (modified) clang-tools-extra/clangd/unittests/PreambleTests.cpp (+5-5) 
- (modified) clang-tools-extra/clangd/unittests/PrerequisiteModulesTest.cpp (+3-3) 
- (modified) clang-tools-extra/clangd/unittests/RenameTests.cpp (+20-3) 
- (modified) clang-tools-extra/clangd/unittests/TUSchedulerTests.cpp (+102-8) 
- (modified) clang-tools-extra/clangd/unittests/TestFS.cpp (+14-12) 
- (modified) clang-tools-extra/clangd/unittests/URITests.cpp (+94) 
- (modified) clang-tools-extra/clangd/unittests/support/PathTests.cpp (+134-10) 
- (modified) clang-tools-extra/clangd/unittests/tweaks/TweakTesting.cpp (+3-3) 
- (modified) llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn (+1) 


``````````diff
diff --git a/clang-tools-extra/clangd/ASTSignals.cpp b/clang-tools-extra/clangd/ASTSignals.cpp
index cffadb091d557..21647994d259e 100644
--- a/clang-tools-extra/clangd/ASTSignals.cpp
+++ b/clang-tools-extra/clangd/ASTSignals.cpp
@@ -19,7 +19,7 @@ ASTSignals ASTSignals::derive(const ParsedAST &AST) {
   trace::Span Span("ASTSignals::derive");
   ASTSignals Signals;
   Signals.InsertionDirective = preferredIncludeDirective(
-      AST.tuPath(), AST.getLangOpts(),
+      AST.tuPath().raw(), AST.getLangOpts(),
       AST.getIncludeStructure().MainFileIncludes, AST.getLocalTopLevelDecls());
   const SourceManager &SM = AST.getSourceManager();
   findExplicitReferences(
diff --git a/clang-tools-extra/clangd/CMakeLists.txt b/clang-tools-extra/clangd/CMakeLists.txt
index 151f4ee028b87..33562a74f212c 100644
--- a/clang-tools-extra/clangd/CMakeLists.txt
+++ b/clang-tools-extra/clangd/CMakeLists.txt
@@ -128,6 +128,7 @@ add_clang_library(clangDaemon STATIC
   index/IndexAction.cpp
   index/MemIndex.cpp
   index/Merge.cpp
+  index/PathIdentity.cpp
   index/ProjectAware.cpp
   index/Ref.cpp
   index/Relation.cpp
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.cpp b/clang-tools-extra/clangd/ClangdLSPServer.cpp
index 43e8b35e45c89..b919293bff69c 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ b/clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -176,13 +176,13 @@ llvm::Error validateEdits(const ClangdServer &Server, const FileEdits &FE) {
   size_t InvalidFileCount = 0;
   llvm::StringRef LastInvalidFile;
   for (const auto &It : FE) {
-    if (auto Draft = Server.getDraft(It.first())) {
+    if (auto Draft = Server.getDraft(It.first)) {
       // If the file is open in user's editor, make sure the version we
       // saw and current version are compatible as this is the text that
       // will be replaced by editors.
       if (!It.second.canApplyTo(*Draft)) {
         ++InvalidFileCount;
-        LastInvalidFile = It.first();
+        LastInvalidFile = It.first.raw();
       }
     }
   }
@@ -831,7 +831,7 @@ void ClangdLSPServer::onCommandApplyTweak(const TweakArgs &Args,
     // FIXME: use documentChanges when SupportDocumentChanges is true.
     WE.changes.emplace();
     for (const auto &It : R->ApplyEdits) {
-      (*WE.changes)[URI::createFile(It.first()).toString()] =
+      (*WE.changes)[URI::createFile(It.first.raw()).toString()] =
           It.second.asTextEdits();
     }
     // ApplyEdit will take care of calling Reply().
@@ -920,7 +920,7 @@ void ClangdLSPServer::onRename(const RenameParams &Params,
                    Result.changes.emplace();
                    for (const auto &Rep : R->GlobalChanges) {
                      (*Result
-                           .changes)[URI::createFile(Rep.first()).toString()] =
+                           .changes)[URI::createFile(Rep.first.raw()).toString()] =
                          Rep.second.asTextEdits();
                    }
                    Reply(Result);
@@ -934,11 +934,11 @@ void ClangdLSPServer::onDocumentDidClose(
 
   {
     std::lock_guard<std::mutex> Lock(DiagRefMutex);
-    DiagRefMap.erase(File);
+    DiagRefMap.erase(File.raw());
   }
   {
     std::lock_guard<std::mutex> HLock(SemanticTokensMutex);
-    LastSemanticTokens.erase(File);
+    LastSemanticTokens.erase(File.raw());
   }
   // clangd will not send updates for this file anymore, so we empty out the
   // list of diagnostics shown on the client (e.g. in the "Problems" pane of
@@ -1202,10 +1202,10 @@ static Location *getToggle(const TextDocumentPositionParams &Point,
   // Toggle only makes sense with two distinct locations.
   if (!Sym.Definition || *Sym.Definition == Sym.PreferredDeclaration)
     return nullptr;
-  if (Sym.Definition->uri.file() == Point.textDocument.uri.file() &&
+  if (Sym.Definition->uri == Point.textDocument.uri &&
       Sym.Definition->range.contains(Point.position))
     return &Sym.PreferredDeclaration;
-  if (Sym.PreferredDeclaration.uri.file() == Point.textDocument.uri.file() &&
+  if (Sym.PreferredDeclaration.uri == Point.textDocument.uri &&
       Sym.PreferredDeclaration.range.contains(Point.position))
     return &*Sym.Definition;
   return nullptr;
@@ -1444,19 +1444,20 @@ void ClangdLSPServer::onCallHierarchyOutgoingCalls(
 void ClangdLSPServer::applyConfiguration(
     const ConfigurationSettings &Settings) {
   // Per-file update to the compilation database.
-  llvm::StringSet<> ModifiedFiles;
+  PathSet ModifiedFiles;
   for (auto &[File, Command] : Settings.compilationDatabaseChanges) {
     auto Cmd =
         tooling::CompileCommand(std::move(Command.workingDirectory), File,
                                 std::move(Command.compilationCommand),
                                 /*Output=*/"");
     if (CDB->setCompileCommand(File, std::move(Cmd))) {
-      ModifiedFiles.insert(File);
+      ModifiedFiles.insert(Path(File));
     }
   }
 
-  Server->reparseOpenFilesIfNeeded(
-      [&](llvm::StringRef File) { return ModifiedFiles.count(File) != 0; });
+  Server->reparseOpenFilesIfNeeded([&](llvm::StringRef File) {
+    return ModifiedFiles.find_as(PathRef(File)) != ModifiedFiles.end();
+  });
 }
 
 void ClangdLSPServer::maybeExportMemoryProfile() {
diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h
index bd9c5e6bc6954..08eb505b4c15e 100644
--- a/clang-tools-extra/clangd/ClangdLSPServer.h
+++ b/clang-tools-extra/clangd/ClangdLSPServer.h
@@ -262,12 +262,11 @@ class ClangdLSPServer : private ClangdServer::Callbacks,
   typedef std::map<DiagKey, ClangdServer::DiagRef>
       DiagnosticToDiagRefMap;
   /// Caches the mapping LSP and clangd-naive diagnostics per file.
-  llvm::StringMap<DiagnosticToDiagRefMap>
-      DiagRefMap;
+  PathMap<DiagnosticToDiagRefMap> DiagRefMap;
 
   // Last semantic-tokens response, for incremental requests.
   std::mutex SemanticTokensMutex;
-  llvm::StringMap<SemanticTokens> LastSemanticTokens;
+  PathMap<SemanticTokens> LastSemanticTokens;
 
   // Most code should not deal with Transport, callMethod, notify directly.
   // Use LSPBinder to handle incoming and outgoing calls.
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp
index 37eb82116f3a9..4feb55a6cc23b 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -62,8 +62,8 @@ namespace clangd {
 namespace {
 
 // Tracks number of times a tweak has been offered.
-static constexpr trace::Metric TweakAvailable(
-    "tweak_available", trace::Metric::Counter, "tweak_id");
+static constexpr trace::Metric
+    TweakAvailable("tweak_available", trace::Metric::Counter, "tweak_id");
 
 // Update the FileIndex with new ASTs and plumb the diagnostics responses.
 struct UpdateIndexCallbacks : public ParsingCallbacks {
@@ -88,15 +88,15 @@ struct UpdateIndexCallbacks : public ParsingCallbacks {
       indexStdlib(CI, std::move(*Loc));
 
     // FIndex outlives the UpdateIndexCallbacks.
-    auto Task = [FIndex(FIndex), Path(Path.str()), Version(Version.str()),
+    auto Task = [FIndex(FIndex), Path(Path.owned()), Version(Version.str()),
                  ASTCtx(std::move(ASTCtx)), PI(std::move(PI))]() mutable {
       trace::Span Tracer("PreambleIndexing");
-      FIndex->updatePreamble(Path, Version, ASTCtx.getASTContext(),
+      FIndex->updatePreamble(Path.raw(), Version, ASTCtx.getASTContext(),
                              ASTCtx.getPreprocessor(), *PI);
     };
 
     if (Tasks) {
-      Tasks->runAsync("Preamble indexing for:" + Path + Version,
+      Tasks->runAsync("Preamble indexing for:" + Path.raw().str() + Version,
                       std::move(Task));
     } else
       Task();
@@ -264,7 +264,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
     BackgroundIdx = std::make_unique<BackgroundIndex>(
         TFS, CDB,
         BackgroundIndexStorage::createDiskBackedStorageFactory(
-            [&CDB](llvm::StringRef File) { return CDB.getProjectInfo(File); }),
+            [&CDB](PathRef File) { return CDB.getProjectInfo(File); }),
         std::move(BGOpts));
     AddIndex(BackgroundIdx.get());
   }
@@ -319,14 +319,14 @@ void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents,
   bool NewFile = WorkScheduler->update(File, Inputs, WantDiags);
   // If we loaded Foo.h, we want to make sure Foo.cpp is indexed.
   if (NewFile && BackgroundIdx)
-    BackgroundIdx->boostRelated(File);
+    BackgroundIdx->boostRelated(File.raw());
 }
 
 void ClangdServer::reparseOpenFilesIfNeeded(
     llvm::function_ref<bool(llvm::StringRef File)> Filter) {
   // Reparse only opened files that were modified.
   for (const Path &FilePath : DraftMgr.getActiveFiles())
-    if (Filter(FilePath))
+    if (Filter(FilePath.raw()))
       if (auto Draft = DraftMgr.getDraft(FilePath)) // else disappeared in race?
         addDocument(FilePath, *Draft->Contents, Draft->Version,
                     WantDiagnostics::Auto);
@@ -343,7 +343,7 @@ std::function<Context(PathRef)>
 ClangdServer::createConfiguredContextProvider(const config::Provider *Provider,
                                               Callbacks *Publish) {
   if (!Provider)
-    return [](llvm::StringRef) { return Context::current().clone(); };
+    return [](PathRef) { return Context::current().clone(); };
 
   struct Impl {
     const config::Provider *Provider;
@@ -411,8 +411,8 @@ ClangdServer::createConfiguredContextProvider(const config::Provider *Provider,
   };
 
   // Copyable wrapper.
-  return [I(std::make_shared<Impl>(Provider, Publish))](llvm::StringRef Path) {
-    return (*I)(Path);
+  return [I(std::make_shared<Impl>(Provider, Publish))](PathRef Path) {
+    return (*I)(Path.raw());
   };
 }
 
@@ -429,7 +429,7 @@ void ClangdServer::codeComplete(PathRef File, Position Pos,
   if (!CodeCompleteOpts.Index) // Respect overridden index.
     CodeCompleteOpts.Index = Index;
 
-  auto Task = [Pos, CodeCompleteOpts, File = File.str(), CB = std::move(CB),
+  auto Task = [Pos, CodeCompleteOpts, File = File.owned(), CB = std::move(CB),
                this](llvm::Expected<InputsAndPreamble> IP) mutable {
     if (!IP)
       return CB(IP.takeError());
@@ -445,7 +445,8 @@ void ClangdServer::codeComplete(PathRef File, Position Pos,
       SpecFuzzyFind.emplace();
       {
         std::lock_guard<std::mutex> Lock(CachedCompletionFuzzyFindRequestMutex);
-        SpecFuzzyFind->CachedReq = CachedCompletionFuzzyFindRequestByFile[File];
+        SpecFuzzyFind->CachedReq =
+            CachedCompletionFuzzyFindRequestByFile[File.raw()];
       }
     }
     ParseInputs ParseInput{IP->Command, &getHeaderFS(), IP->Contents.str()};
@@ -479,7 +480,8 @@ void ClangdServer::codeComplete(PathRef File, Position Pos,
       return;
     if (SpecFuzzyFind->NewReq) {
       std::lock_guard<std::mutex> Lock(CachedCompletionFuzzyFindRequestMutex);
-      CachedCompletionFuzzyFindRequestByFile[File] = *SpecFuzzyFind->NewReq;
+      CachedCompletionFuzzyFindRequestByFile[File.raw()] =
+          *SpecFuzzyFind->NewReq;
     }
     // Explicitly block until async task completes, this is fine as we've
     // already provided reply to the client and running as a preamble task
@@ -501,7 +503,7 @@ void ClangdServer::signatureHelp(PathRef File, Position Pos,
                                  MarkupKind DocumentationFormat,
                                  Callback<SignatureHelp> CB) {
 
-  auto Action = [Pos, File = File.str(), CB = std::move(CB),
+  auto Action = [Pos, File = File.owned(), CB = std::move(CB),
                  DocumentationFormat,
                  this](llvm::Expected<InputsAndPreamble> IP) mutable {
     if (!IP)
@@ -549,12 +551,13 @@ void ClangdServer::formatFile(PathRef File, const std::vector<Range> &Rngs,
   }
 
   // Call clang-format.
-  auto Action = [File = File.str(), Code = std::move(*Code),
+  auto Action = [File = File.owned(), Code = std::move(*Code),
                  Ranges = std::move(RequestedRanges), CB = std::move(CB),
                  this]() mutable {
-    format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS, true);
+    format::FormatStyle Style =
+        getFormatStyleForFile(File.raw(), Code, TFS, true);
     tooling::Replacements IncludeReplaces =
-        format::sortIncludes(Style, Code, Ranges, File);
+        format::sortIncludes(Style, Code, Ranges, File.raw());
     auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces);
     if (!Changed)
       return CB(Changed.takeError());
@@ -562,9 +565,9 @@ void ClangdServer::formatFile(PathRef File, const std::vector<Range> &Rngs,
     CB(IncludeReplaces.merge(format::reformat(
         Style, *Changed,
         tooling::calculateRangesAfterReplacements(IncludeReplaces, Ranges),
-        File)));
+        File.raw())));
   };
-  WorkScheduler->runQuick("Format", File, std::move(Action));
+  WorkScheduler->runQuick("Format", File.raw(), std::move(Action));
 }
 
 void ClangdServer::formatOnType(PathRef File, Position Pos,
@@ -577,24 +580,24 @@ void ClangdServer::formatOnType(PathRef File, Position Pos,
   llvm::Expected<size_t> CursorPos = positionToOffset(*Code, Pos);
   if (!CursorPos)
     return CB(CursorPos.takeError());
-  auto Action = [File = File.str(), Code = std::move(*Code),
+  auto Action = [File = File.owned(), Code = std::move(*Code),
                  TriggerText = TriggerText.str(), CursorPos = *CursorPos,
                  CB = std::move(CB), this]() mutable {
-    auto Style = getFormatStyleForFile(File, Code, TFS, false);
+    auto Style = getFormatStyleForFile(File.raw(), Code, TFS, false);
     std::vector<TextEdit> Result;
     for (const tooling::Replacement &R :
          formatIncremental(Code, CursorPos, TriggerText, Style))
       Result.push_back(replacementToEdit(Code, R));
     return CB(Result);
   };
-  WorkScheduler->runQuick("FormatOnType", File, std::move(Action));
+  WorkScheduler->runQuick("FormatOnType", File.raw(), std::move(Action));
 }
 
 void ClangdServer::prepareRename(PathRef File, Position Pos,
                                  std::optional<std::string> NewName,
                                  const RenameOptions &RenameOpts,
                                  Callback<RenameResult> CB) {
-  auto Action = [Pos, File = File.str(), CB = std::move(CB),
+  auto Action = [Pos, File = File.owned(), CB = std::move(CB),
                  NewName = std::move(NewName),
                  RenameOpts](llvm::Expected<InputsAndAST> InpAST) mutable {
     if (!InpAST)
@@ -603,7 +606,7 @@ void ClangdServer::prepareRename(PathRef File, Position Pos,
     // only need main-file references
     auto Results =
         clangd::rename({Pos, NewName.value_or("__clangd_rename_placeholder"),
-                        InpAST->AST, File, /*FS=*/nullptr,
+                        InpAST->AST, File.raw(), /*FS=*/nullptr,
                         /*Index=*/nullptr, RenameOpts});
     if (!Results) {
       // LSP says to return null on failure, but that will result in a generic
@@ -619,7 +622,7 @@ void ClangdServer::prepareRename(PathRef File, Position Pos,
 void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
                           const RenameOptions &Opts,
                           Callback<RenameResult> CB) {
-  auto Action = [File = File.str(), NewName = NewName.str(), Pos, Opts,
+  auto Action = [File = File.owned(), NewName = NewName.str(), Pos, Opts,
                  CB = std::move(CB),
                  this](llvm::Expected<InputsAndAST> InpAST) mutable {
     // Tracks number of files edited per invocation.
@@ -627,18 +630,17 @@ void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
                                                trace::Metric::Distribution);
     if (!InpAST)
       return CB(InpAST.takeError());
-    auto R = clangd::rename({Pos, NewName, InpAST->AST, File,
+    auto R = clangd::rename({Pos, NewName, InpAST->AST, File.raw(),
                              DirtyFS->view(std::nullopt), Index, Opts});
     if (!R)
       return CB(R.takeError());
 
     if (Opts.WantFormat) {
-      auto Style = getFormatStyleForFile(File, InpAST->Inputs.Contents,
+      auto Style = getFormatStyleForFile(File.raw(), InpAST->Inputs.Contents,
                                          *InpAST->Inputs.TFS, false);
       llvm::Error Err = llvm::Error::success();
       for (auto &E : R->GlobalChanges)
-        Err =
-            llvm::joinErrors(reformatEdit(E.getValue(), Style), std::move(Err));
+        Err = llvm::joinErrors(reformatEdit(E.second, Style), std::move(Err));
 
       if (Err)
         return CB(std::move(Err));
@@ -765,7 +767,7 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID,
   static constexpr trace::Metric TweakFailed(
       "tweak_failed", trace::Metric::Counter, "tweak_id");
   TweakAttempt.record(1, TweakID);
-  auto Action = [File = File.str(), Sel, TweakID = TweakID.str(),
+  auto Action = [File = File.owned(), Sel, TweakID = TweakID.str(),
                  CB = std::move(CB),
                  this](Expected<InputsAndAST> InpAST) mutable {
     if (!InpAST)
@@ -791,9 +793,9 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID,
       for (auto &It : (*Effect)->ApplyEdits) {
         Edit &E = It.second;
         format::FormatStyle Style =
-            getFormatStyleForFile(File, E.InitialCode, TFS, false);
+            getFormatStyleForFile(File.raw(), E.InitialCode, TFS, false);
         if (llvm::Error Err = reformatEdit(E, Style))
-          elog("Failed to format {0}: {1}", It.first(), std::move(Err));
+          elog("Failed to format {0}: {1}", It.first, std::move(Err));
       }
     } else {
       TweakFailed.record(1, TweakID);
@@ -826,7 +828,7 @@ void ClangdServer::switchSourceHeader(
   if (auto CorrespondingFile =
           getCorrespondingHeaderOrSource(Path, TFS.view(std::nullopt)))
     return CB(std::move(CorrespondingFile));
-  auto Action = [Path = Path.str(), CB = std::move(CB),
+  auto Action = [Path = Path.owned(), CB = std::move(CB),
                  this](llvm::Expected<InputsAndAST> InpAST) mutable {
     if (!InpAST)
       return CB(InpAST.takeError());
@@ -849,12 +851,12 @@ void ClangdServer::findDocumentHighlights(
 
 void ClangdServer::findHover(PathRef File, Position Pos,
                              Callback<std::optional<HoverInfo>> CB) {
-  auto Action = [File = File.str(), Pos, CB = std::move(CB),
+  auto Action = [File = File.owned(), Pos, CB = std::move(CB),
                  this](llvm::Expected<InputsAndAST> InpAST) mutable {
     if (!InpAST)
       return CB(InpAST.takeError());
     format::FormatStyle Style = getFormatStyleForFile(
-        File, InpAST->Inputs.Contents, *InpAST->Inputs.TFS, false);
+        File.raw(), InpAST->Inputs.Contents, *InpAST->Inputs.TFS, false);
     CB(clangd::getHover(InpAST->AST, Pos, std::move(Style), Index));
   };
 
@@ -864,7 +866,8 @@ void ClangdServer::findHover(PathRef File, Position Pos,
 void ClangdServer::typeHierarchy(PathRef File, Position Pos, int Resolve,
                                  TypeHierarchyDirection Direction,
                                  Callback<std::vector<TypeHierarchyItem>> CB) {
-  auto Action = [File = File.str(), Pos, Resolve, Direction, CB = std::move(CB),
+  auto Action = [File = File.owned(), Pos, Resolve, Direction,
+                 CB = std::move(CB),
                  this](Expected<InputsAndAST> InpAST) mutable {
     if (!InpAST)
       return CB(InpAST.takeError());
@@ -903,7 +906,7 @@ void ClangdServer::resolveTypeHierarchy(
 
 void ClangdServer::prepareCallHierarchy(
     PathRef File, Position Pos, Callback<std::vector<CallHierarchyItem>> CB) {
-  auto Action = [File = File.str(), Pos,
+  auto Action = [File = File.owned(), Pos,
                  CB = std::move(CB)](Expected<InputsAndAST> InpAST) mutable {
     if (!InpAST)
       return CB(InpAST.takeError());
@@ -985,7 +988,7 @@ void ClangdServer::foldingRanges(llvm::StringRef File,
   WorkScheduler->runQuick("FoldingRanges", File, std::move(Action));
 }
 
-void ClangdServer::findType(llvm::StringRef File, Position Pos,
+void ClangdServer::findType(PathRef File, Position Pos,
                             Callback<std::vector<LocatedSymbol>> CB) {
   auto Action = [Pos, CB = std::move(CB),
                  this](llvm::Expected<InputsAndAST> InpAST) mutable {
diff --git a/clang-tools-extra/c...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/221921


More information about the cfe-commits mailing list