[PATCH] D95206: [clangd][SwapIndex] ensure that the old index is alive while we are using it via the function returned by `SwapIndex::indexedFiles()` call
This revision was automatically updated to reflect the committed changes. Closed by commit rG7388c3468595: [clangd][SwapIndex] ensure that the old index is alive while we are using it… (authored by ArcsinX). Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95206/new/ https://reviews.llvm.org/D95206 Files: clang-tools-extra/clangd/index/Index.cpp clang-tools-extra/clangd/index/Merge.cpp Index: clang-tools-extra/clangd/index/Merge.cpp === --- clang-tools-extra/clangd/index/Merge.cpp +++ clang-tools-extra/clangd/index/Merge.cpp @@ -44,21 +44,23 @@ SymbolSlab Dyn = std::move(DynB).build(); llvm::DenseSet SeenDynamicSymbols; - auto DynamicContainsFile = Dynamic->indexedFiles(); - More |= Static->fuzzyFind(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -auto DynS = Dyn.find(S.ID); -++StaticCount; -if (DynS == Dyn.end()) - return Callback(S); -++MergedCount; -SeenDynamicSymbols.insert(S.ID); -Callback(mergeSymbol(*DynS, S)); - }); + { +auto DynamicContainsFile = Dynamic->indexedFiles(); +More |= Static->fuzzyFind(Req, [&](const Symbol &S) { + // We expect the definition to see the canonical declaration, so it seems + // to be enough to check only the definition if it exists. + if (DynamicContainsFile(S.Definition ? S.Definition.FileURI + : S.CanonicalDeclaration.FileURI)) +return; + auto DynS = Dyn.find(S.ID); + ++StaticCount; + if (DynS == Dyn.end()) +return Callback(S); + ++MergedCount; + SeenDynamicSymbols.insert(S.ID); + Callback(mergeSymbol(*DynS, S)); +}); + } SPAN_ATTACH(Tracer, "dynamic", DynamicCount); SPAN_ATTACH(Tracer, "static", StaticCount); SPAN_ATTACH(Tracer, "merged", MergedCount); @@ -77,20 +79,22 @@ Dynamic->lookup(Req, [&](const Symbol &S) { B.insert(S); }); auto RemainingIDs = Req.IDs; - auto DynamicContainsFile = Dynamic->indexedFiles(); - Static->lookup(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -const Symbol *Sym = B.find(S.ID); -RemainingIDs.erase(S.ID); -if (!Sym) - Callback(S); -else - Callback(mergeSymbol(*Sym, S)); - }); + { +auto DynamicContainsFile = Dynamic->indexedFiles(); +Static->lookup(Req, [&](const Symbol &S) { + // We expect the definition to see the canonical declaration, so it seems + // to be enough to check only the definition if it exists. + if (DynamicContainsFile(S.Definition ? S.Definition.FileURI + : S.CanonicalDeclaration.FileURI)) +return; + const Symbol *Sym = B.find(S.ID); + RemainingIDs.erase(S.ID); + if (!Sym) +Callback(S); + else +Callback(mergeSymbol(*Sym, S)); +}); + } for (const auto &ID : RemainingIDs) if (const Symbol *Sym = B.find(ID)) Callback(*Sym); Index: clang-tools-extra/clangd/index/Index.cpp === --- clang-tools-extra/clangd/index/Index.cpp +++ clang-tools-extra/clangd/index/Index.cpp @@ -78,7 +78,13 @@ llvm::unique_function SwapIndex::indexedFiles() const { - return snapshot()->indexedFiles(); + // The index snapshot should outlive this method return value. + auto SnapShot = snapshot(); + auto IndexedFiles = SnapShot->indexedFiles(); + return [KeepAlive{std::move(SnapShot)}, + IndexContainsFile{std::move(IndexedFiles)}](llvm::StringRef File) { +return IndexContainsFile(File); + }; } size_t SwapIndex::estimateMemoryUsage() const { Index: clang-tools-extra/clangd/index/Merge.cpp === --- clang-tools-extra/clangd/index/Merge.cpp +++ clang-tools-extra/clangd/index/Merge.cpp @@ -44,21 +44,23 @@ SymbolSlab Dyn = std::move(DynB).build(); llvm::DenseSet SeenDynamicSymbols; - auto DynamicContainsFile = Dynamic->indexedFiles(); - More |= Static->fuzzyFind(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -auto DynS = Dyn
[PATCH] D95206: [clangd][SwapIndex] ensure that the old index is alive while we are using it via the function returned by `SwapIndex::indexedFiles()` call
ArcsinX updated this revision to Diff 318474. ArcsinX added a comment. Fix format Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95206/new/ https://reviews.llvm.org/D95206 Files: clang-tools-extra/clangd/index/Index.cpp clang-tools-extra/clangd/index/Merge.cpp Index: clang-tools-extra/clangd/index/Merge.cpp === --- clang-tools-extra/clangd/index/Merge.cpp +++ clang-tools-extra/clangd/index/Merge.cpp @@ -44,21 +44,23 @@ SymbolSlab Dyn = std::move(DynB).build(); llvm::DenseSet SeenDynamicSymbols; - auto DynamicContainsFile = Dynamic->indexedFiles(); - More |= Static->fuzzyFind(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -auto DynS = Dyn.find(S.ID); -++StaticCount; -if (DynS == Dyn.end()) - return Callback(S); -++MergedCount; -SeenDynamicSymbols.insert(S.ID); -Callback(mergeSymbol(*DynS, S)); - }); + { +auto DynamicContainsFile = Dynamic->indexedFiles(); +More |= Static->fuzzyFind(Req, [&](const Symbol &S) { + // We expect the definition to see the canonical declaration, so it seems + // to be enough to check only the definition if it exists. + if (DynamicContainsFile(S.Definition ? S.Definition.FileURI + : S.CanonicalDeclaration.FileURI)) +return; + auto DynS = Dyn.find(S.ID); + ++StaticCount; + if (DynS == Dyn.end()) +return Callback(S); + ++MergedCount; + SeenDynamicSymbols.insert(S.ID); + Callback(mergeSymbol(*DynS, S)); +}); + } SPAN_ATTACH(Tracer, "dynamic", DynamicCount); SPAN_ATTACH(Tracer, "static", StaticCount); SPAN_ATTACH(Tracer, "merged", MergedCount); @@ -77,20 +79,22 @@ Dynamic->lookup(Req, [&](const Symbol &S) { B.insert(S); }); auto RemainingIDs = Req.IDs; - auto DynamicContainsFile = Dynamic->indexedFiles(); - Static->lookup(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -const Symbol *Sym = B.find(S.ID); -RemainingIDs.erase(S.ID); -if (!Sym) - Callback(S); -else - Callback(mergeSymbol(*Sym, S)); - }); + { +auto DynamicContainsFile = Dynamic->indexedFiles(); +Static->lookup(Req, [&](const Symbol &S) { + // We expect the definition to see the canonical declaration, so it seems + // to be enough to check only the definition if it exists. + if (DynamicContainsFile(S.Definition ? S.Definition.FileURI + : S.CanonicalDeclaration.FileURI)) +return; + const Symbol *Sym = B.find(S.ID); + RemainingIDs.erase(S.ID); + if (!Sym) +Callback(S); + else +Callback(mergeSymbol(*Sym, S)); +}); + } for (const auto &ID : RemainingIDs) if (const Symbol *Sym = B.find(ID)) Callback(*Sym); Index: clang-tools-extra/clangd/index/Index.cpp === --- clang-tools-extra/clangd/index/Index.cpp +++ clang-tools-extra/clangd/index/Index.cpp @@ -78,7 +78,13 @@ llvm::unique_function SwapIndex::indexedFiles() const { - return snapshot()->indexedFiles(); + // The index snapshot should outlive this method return value. + auto SnapShot = snapshot(); + auto IndexedFiles = SnapShot->indexedFiles(); + return [KeepAlive{std::move(SnapShot)}, + IndexContainsFile{std::move(IndexedFiles)}](llvm::StringRef File) { +return IndexContainsFile(File); + }; } size_t SwapIndex::estimateMemoryUsage() const { Index: clang-tools-extra/clangd/index/Merge.cpp === --- clang-tools-extra/clangd/index/Merge.cpp +++ clang-tools-extra/clangd/index/Merge.cpp @@ -44,21 +44,23 @@ SymbolSlab Dyn = std::move(DynB).build(); llvm::DenseSet SeenDynamicSymbols; - auto DynamicContainsFile = Dynamic->indexedFiles(); - More |= Static->fuzzyFind(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -auto DynS = Dyn.find(S.ID); -++StaticCount; -if (DynS == Dyn.end()) - return Callback(S); -++MergedCount; -SeenDynamicS
[PATCH] D95206: [clangd][SwapIndex] ensure that the old index is alive while we are using it via the function returned by `SwapIndex::indexedFiles()` call
ArcsinX updated this revision to Diff 318470. ArcsinX added a comment. Call snapshot() only once to avoid possible race. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95206/new/ https://reviews.llvm.org/D95206 Files: clang-tools-extra/clangd/index/Index.cpp clang-tools-extra/clangd/index/Merge.cpp Index: clang-tools-extra/clangd/index/Merge.cpp === --- clang-tools-extra/clangd/index/Merge.cpp +++ clang-tools-extra/clangd/index/Merge.cpp @@ -44,21 +44,23 @@ SymbolSlab Dyn = std::move(DynB).build(); llvm::DenseSet SeenDynamicSymbols; - auto DynamicContainsFile = Dynamic->indexedFiles(); - More |= Static->fuzzyFind(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -auto DynS = Dyn.find(S.ID); -++StaticCount; -if (DynS == Dyn.end()) - return Callback(S); -++MergedCount; -SeenDynamicSymbols.insert(S.ID); -Callback(mergeSymbol(*DynS, S)); - }); + { +auto DynamicContainsFile = Dynamic->indexedFiles(); +More |= Static->fuzzyFind(Req, [&](const Symbol &S) { + // We expect the definition to see the canonical declaration, so it seems + // to be enough to check only the definition if it exists. + if (DynamicContainsFile(S.Definition ? S.Definition.FileURI + : S.CanonicalDeclaration.FileURI)) +return; + auto DynS = Dyn.find(S.ID); + ++StaticCount; + if (DynS == Dyn.end()) +return Callback(S); + ++MergedCount; + SeenDynamicSymbols.insert(S.ID); + Callback(mergeSymbol(*DynS, S)); +}); + } SPAN_ATTACH(Tracer, "dynamic", DynamicCount); SPAN_ATTACH(Tracer, "static", StaticCount); SPAN_ATTACH(Tracer, "merged", MergedCount); @@ -77,20 +79,22 @@ Dynamic->lookup(Req, [&](const Symbol &S) { B.insert(S); }); auto RemainingIDs = Req.IDs; - auto DynamicContainsFile = Dynamic->indexedFiles(); - Static->lookup(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -const Symbol *Sym = B.find(S.ID); -RemainingIDs.erase(S.ID); -if (!Sym) - Callback(S); -else - Callback(mergeSymbol(*Sym, S)); - }); + { +auto DynamicContainsFile = Dynamic->indexedFiles(); +Static->lookup(Req, [&](const Symbol &S) { + // We expect the definition to see the canonical declaration, so it seems + // to be enough to check only the definition if it exists. + if (DynamicContainsFile(S.Definition ? S.Definition.FileURI + : S.CanonicalDeclaration.FileURI)) +return; + const Symbol *Sym = B.find(S.ID); + RemainingIDs.erase(S.ID); + if (!Sym) +Callback(S); + else +Callback(mergeSymbol(*Sym, S)); +}); + } for (const auto &ID : RemainingIDs) if (const Symbol *Sym = B.find(ID)) Callback(*Sym); Index: clang-tools-extra/clangd/index/Index.cpp === --- clang-tools-extra/clangd/index/Index.cpp +++ clang-tools-extra/clangd/index/Index.cpp @@ -78,7 +78,12 @@ llvm::unique_function SwapIndex::indexedFiles() const { - return snapshot()->indexedFiles(); + // The index snapshot should outlive this method return value. + auto SnapShot = snapshot(); + auto IndexedFiles = SnapShot->indexedFiles(); + return [KeepAlive{std::move(SnapShot)}, + IndexContainsFile{std::move(IndexedFiles)}]( + llvm::StringRef File) { return IndexContainsFile(File); }; } size_t SwapIndex::estimateMemoryUsage() const { Index: clang-tools-extra/clangd/index/Merge.cpp === --- clang-tools-extra/clangd/index/Merge.cpp +++ clang-tools-extra/clangd/index/Merge.cpp @@ -44,21 +44,23 @@ SymbolSlab Dyn = std::move(DynB).build(); llvm::DenseSet SeenDynamicSymbols; - auto DynamicContainsFile = Dynamic->indexedFiles(); - More |= Static->fuzzyFind(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -auto DynS = Dyn.find(S.ID); -++StaticCount; -if (DynS == Dyn.end()) - return Call
[PATCH] D95206: [clangd][SwapIndex] ensure that the old index is alive while we are using it via the function returned by `SwapIndex::indexedFiles()` call
sammccall accepted this revision. sammccall added a comment. This revision is now accepted and ready to land. Thanks, I'd seen these crashes but not manage to track down yet! LG with one fix Comment at: clang-tools-extra/clangd/index/Index.cpp:81 SwapIndex::indexedFiles() const { - return snapshot()->indexedFiles(); + return [KeepAlive = snapshot(), IndexedFiles = snapshot()->indexedFiles()]( + llvm::StringRef File) { return IndexedFiles(File); }; Calling snapshot() twice introduces a race - we may keep the wrong one alive. Evaluate snapshot first into a variable, then call indexedFiles, then move both into the lambda? Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95206/new/ https://reviews.llvm.org/D95206 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D95206: [clangd][SwapIndex] ensure that the old index is alive while we are using it via the function returned by `SwapIndex::indexedFiles()` call
ArcsinX updated this revision to Diff 318442. ArcsinX added a comment. Fix format Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95206/new/ https://reviews.llvm.org/D95206 Files: clang-tools-extra/clangd/index/Index.cpp clang-tools-extra/clangd/index/Merge.cpp Index: clang-tools-extra/clangd/index/Merge.cpp === --- clang-tools-extra/clangd/index/Merge.cpp +++ clang-tools-extra/clangd/index/Merge.cpp @@ -44,21 +44,23 @@ SymbolSlab Dyn = std::move(DynB).build(); llvm::DenseSet SeenDynamicSymbols; - auto DynamicContainsFile = Dynamic->indexedFiles(); - More |= Static->fuzzyFind(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -auto DynS = Dyn.find(S.ID); -++StaticCount; -if (DynS == Dyn.end()) - return Callback(S); -++MergedCount; -SeenDynamicSymbols.insert(S.ID); -Callback(mergeSymbol(*DynS, S)); - }); + { +auto DynamicContainsFile = Dynamic->indexedFiles(); +More |= Static->fuzzyFind(Req, [&](const Symbol &S) { + // We expect the definition to see the canonical declaration, so it seems + // to be enough to check only the definition if it exists. + if (DynamicContainsFile(S.Definition ? S.Definition.FileURI + : S.CanonicalDeclaration.FileURI)) +return; + auto DynS = Dyn.find(S.ID); + ++StaticCount; + if (DynS == Dyn.end()) +return Callback(S); + ++MergedCount; + SeenDynamicSymbols.insert(S.ID); + Callback(mergeSymbol(*DynS, S)); +}); + } SPAN_ATTACH(Tracer, "dynamic", DynamicCount); SPAN_ATTACH(Tracer, "static", StaticCount); SPAN_ATTACH(Tracer, "merged", MergedCount); @@ -77,20 +79,22 @@ Dynamic->lookup(Req, [&](const Symbol &S) { B.insert(S); }); auto RemainingIDs = Req.IDs; - auto DynamicContainsFile = Dynamic->indexedFiles(); - Static->lookup(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -const Symbol *Sym = B.find(S.ID); -RemainingIDs.erase(S.ID); -if (!Sym) - Callback(S); -else - Callback(mergeSymbol(*Sym, S)); - }); + { +auto DynamicContainsFile = Dynamic->indexedFiles(); +Static->lookup(Req, [&](const Symbol &S) { + // We expect the definition to see the canonical declaration, so it seems + // to be enough to check only the definition if it exists. + if (DynamicContainsFile(S.Definition ? S.Definition.FileURI + : S.CanonicalDeclaration.FileURI)) +return; + const Symbol *Sym = B.find(S.ID); + RemainingIDs.erase(S.ID); + if (!Sym) +Callback(S); + else +Callback(mergeSymbol(*Sym, S)); +}); + } for (const auto &ID : RemainingIDs) if (const Symbol *Sym = B.find(ID)) Callback(*Sym); Index: clang-tools-extra/clangd/index/Index.cpp === --- clang-tools-extra/clangd/index/Index.cpp +++ clang-tools-extra/clangd/index/Index.cpp @@ -78,7 +78,8 @@ llvm::unique_function SwapIndex::indexedFiles() const { - return snapshot()->indexedFiles(); + return [KeepAlive = snapshot(), IndexedFiles = snapshot()->indexedFiles()]( + llvm::StringRef File) { return IndexedFiles(File); }; } size_t SwapIndex::estimateMemoryUsage() const { Index: clang-tools-extra/clangd/index/Merge.cpp === --- clang-tools-extra/clangd/index/Merge.cpp +++ clang-tools-extra/clangd/index/Merge.cpp @@ -44,21 +44,23 @@ SymbolSlab Dyn = std::move(DynB).build(); llvm::DenseSet SeenDynamicSymbols; - auto DynamicContainsFile = Dynamic->indexedFiles(); - More |= Static->fuzzyFind(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -auto DynS = Dyn.find(S.ID); -++StaticCount; -if (DynS == Dyn.end()) - return Callback(S); -++MergedCount; -SeenDynamicSymbols.insert(S.ID); -Callback(mergeSymbol(*DynS, S)); - }); + { +auto DynamicContainsFile = Dynamic->indexedFiles(); +More |= Static->fuzzyFind(Req, [
[PATCH] D95206: [clangd][SwapIndex] ensure that the old index is alive while we are using it via the function returned by `SwapIndex::indexedFiles()` call
ArcsinX created this revision. ArcsinX added reviewers: sammccall, kadircet. Herald added subscribers: usaxena95, arphaman. ArcsinX requested review of this revision. Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov. Herald added a project: clang. Without this patch the old index could be freed, but there still could be tries to access it via the function returned by `SwapIndex::indexedFiles()` call. This leads to hard to reproduce clangd crashes at code completion. This patch keeps the old index alive until the function returned by `SwapIndex::indexedFiles()` call is alive. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D95206 Files: clang-tools-extra/clangd/index/Index.cpp clang-tools-extra/clangd/index/Merge.cpp Index: clang-tools-extra/clangd/index/Merge.cpp === --- clang-tools-extra/clangd/index/Merge.cpp +++ clang-tools-extra/clangd/index/Merge.cpp @@ -44,21 +44,23 @@ SymbolSlab Dyn = std::move(DynB).build(); llvm::DenseSet SeenDynamicSymbols; - auto DynamicContainsFile = Dynamic->indexedFiles(); - More |= Static->fuzzyFind(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -auto DynS = Dyn.find(S.ID); -++StaticCount; -if (DynS == Dyn.end()) - return Callback(S); -++MergedCount; -SeenDynamicSymbols.insert(S.ID); -Callback(mergeSymbol(*DynS, S)); - }); + { +auto DynamicContainsFile = Dynamic->indexedFiles(); +More |= Static->fuzzyFind(Req, [&](const Symbol &S) { + // We expect the definition to see the canonical declaration, so it seems + // to be enough to check only the definition if it exists. + if (DynamicContainsFile(S.Definition ? S.Definition.FileURI + : S.CanonicalDeclaration.FileURI)) +return; + auto DynS = Dyn.find(S.ID); + ++StaticCount; + if (DynS == Dyn.end()) +return Callback(S); + ++MergedCount; + SeenDynamicSymbols.insert(S.ID); + Callback(mergeSymbol(*DynS, S)); +}); + } SPAN_ATTACH(Tracer, "dynamic", DynamicCount); SPAN_ATTACH(Tracer, "static", StaticCount); SPAN_ATTACH(Tracer, "merged", MergedCount); @@ -77,20 +79,22 @@ Dynamic->lookup(Req, [&](const Symbol &S) { B.insert(S); }); auto RemainingIDs = Req.IDs; - auto DynamicContainsFile = Dynamic->indexedFiles(); - Static->lookup(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (DynamicContainsFile(S.Definition ? S.Definition.FileURI - : S.CanonicalDeclaration.FileURI)) - return; -const Symbol *Sym = B.find(S.ID); -RemainingIDs.erase(S.ID); -if (!Sym) - Callback(S); -else - Callback(mergeSymbol(*Sym, S)); - }); + { +auto DynamicContainsFile = Dynamic->indexedFiles(); +Static->lookup(Req, [&](const Symbol &S) { + // We expect the definition to see the canonical declaration, so it seems + // to be enough to check only the definition if it exists. + if (DynamicContainsFile(S.Definition ? S.Definition.FileURI + : S.CanonicalDeclaration.FileURI)) +return; + const Symbol *Sym = B.find(S.ID); + RemainingIDs.erase(S.ID); + if (!Sym) +Callback(S); + else +Callback(mergeSymbol(*Sym, S)); +}); + } for (const auto &ID : RemainingIDs) if (const Symbol *Sym = B.find(ID)) Callback(*Sym); Index: clang-tools-extra/clangd/index/Index.cpp === --- clang-tools-extra/clangd/index/Index.cpp +++ clang-tools-extra/clangd/index/Index.cpp @@ -78,7 +78,10 @@ llvm::unique_function SwapIndex::indexedFiles() const { - return snapshot()->indexedFiles(); + return [ KeepAlive = snapshot(), + IndexedFiles = snapshot()->indexedFiles() ](llvm::StringRef File) { +return IndexedFiles(File); + }; } size_t SwapIndex::estimateMemoryUsage() const { Index: clang-tools-extra/clangd/index/Merge.cpp === --- clang-tools-extra/clangd/index/Merge.cpp +++ clang-tools-extra/clangd/index/Merge.cpp @@ -44,21 +44,23 @@ SymbolSlab Dyn = std::move(DynB).build(); llvm::DenseSet SeenDynamicSymbols; - auto DynamicContainsFile = Dynamic->indexedFiles(); - More |= Static->fuzzyFind(Req, [&](const Symbol &S) { -// We expect the definition to see the canonical declaration, so it seems -// to be enough to check only the definition if it exists. -if (D