[clang-tools-extra] [clangd] Store full decl/def range with symbol locations (PR #118102)
Christian Kandeler via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 5 02:11:10 PST 2024
https://github.com/ckandeler updated https://github.com/llvm/llvm-project/pull/118102
>From c44237813fb3357dee3f7d17048a7178e67a2422 Mon Sep 17 00:00:00 2001
From: Christian Kandeler <christian.kandeler at qt.io>
Date: Wed, 27 Nov 2024 13:47:32 +0100
Subject: [PATCH] [clangd] Store full decl/def range with symbol locations
Apart from fixing the linked issue, this is also necessary
for supporting LSP's LocationLink feature and for finding
proper insertion locations in the DefineOutline tweak.
Memory consumption of the background index grows by about ~2.5%.
Closes https://github.com/clangd/clangd/issues/59
---
clang-tools-extra/clangd/CodeComplete.cpp | 4 +-
clang-tools-extra/clangd/FindSymbols.cpp | 34 ++++--
clang-tools-extra/clangd/FindSymbols.h | 8 +-
.../clangd/HeaderSourceSwitch.cpp | 4 +-
clang-tools-extra/clangd/IncludeFixer.cpp | 6 +-
clang-tools-extra/clangd/Quality.cpp | 2 +-
clang-tools-extra/clangd/XRefs.cpp | 65 ++++++-----
clang-tools-extra/clangd/index/FileIndex.cpp | 6 +-
clang-tools-extra/clangd/index/Index.h | 2 +-
clang-tools-extra/clangd/index/Merge.cpp | 13 ++-
clang-tools-extra/clangd/index/Ref.h | 11 +-
.../clangd/index/Serialization.cpp | 34 ++++--
clang-tools-extra/clangd/index/StdLib.cpp | 12 +-
clang-tools-extra/clangd/index/Symbol.h | 8 +-
.../clangd/index/SymbolCollector.cpp | 89 +++++++++++----
.../clangd/index/SymbolCollector.h | 3 +-
.../clangd/index/SymbolLocation.cpp | 11 +-
.../clangd/index/SymbolLocation.h | 103 +++++++++++-------
.../clangd/index/YAMLSerialization.cpp | 37 +++++--
clang-tools-extra/clangd/index/dex/Dex.cpp | 4 +-
clang-tools-extra/clangd/refactor/Rename.cpp | 4 +-
.../clangd/test/Inputs/symbols.test.yaml | 17 ++-
.../index-serialization/Inputs/sample.idx | Bin 470 -> 496 bytes
.../clangd/test/type-hierarchy-ext.test | 8 +-
.../clangd/test/type-hierarchy.test | 8 +-
.../clangd/unittests/BackgroundIndexTests.cpp | 4 +-
.../clangd/unittests/CodeCompleteTests.cpp | 18 +--
.../clangd/unittests/DexTests.cpp | 5 +-
.../clangd/unittests/DiagnosticsTests.cpp | 13 ++-
.../clangd/unittests/FileIndexTests.cpp | 14 +--
.../clangd/unittests/IndexTests.cpp | 45 ++++----
.../clangd/unittests/SerializationTests.cpp | 23 +++-
.../clangd/unittests/SymbolCollectorTests.cpp | 12 +-
33 files changed, 388 insertions(+), 239 deletions(-)
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index 2c2d5f0b5ac924..04e4aa2d2d1ca9 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -418,7 +418,7 @@ struct CodeCompletionBuilder {
auto Inserted = [&](llvm::StringRef Header)
-> llvm::Expected<std::pair<std::string, bool>> {
auto ResolvedDeclaring =
- URI::resolve(C.IndexResult->CanonicalDeclaration.FileURI, FileName);
+ URI::resolve(C.IndexResult->CanonicalDeclaration.fileURI(), FileName);
if (!ResolvedDeclaring)
return ResolvedDeclaring.takeError();
auto ResolvedInserted = toHeaderFile(Header, FileName);
@@ -451,7 +451,7 @@ struct CodeCompletionBuilder {
} else
log("Failed to generate include insertion edits for adding header "
"(FileURI='{0}', IncludeHeader='{1}') into {2}: {3}",
- C.IndexResult->CanonicalDeclaration.FileURI, Inc.Header, FileName,
+ C.IndexResult->CanonicalDeclaration.fileURI(), Inc.Header, FileName,
ToInclude.takeError());
}
// Prefer includes that do not need edits (i.e. already exist).
diff --git a/clang-tools-extra/clangd/FindSymbols.cpp b/clang-tools-extra/clangd/FindSymbols.cpp
index 84bcbc1f2ddd3f..646cb261309c80 100644
--- a/clang-tools-extra/clangd/FindSymbols.cpp
+++ b/clang-tools-extra/clangd/FindSymbols.cpp
@@ -54,9 +54,19 @@ bool approximateScopeMatch(llvm::StringRef Scope, llvm::StringRef Query) {
return Query.empty();
}
+Range indexToLSPRange(const SymbolPosition &SrcStart,
+ const SymbolPosition &SrcEnd) {
+ Position Start, End;
+ Start.line = SrcStart.line();
+ Start.character = SrcStart.column();
+ End.line = SrcEnd.line();
+ End.character = SrcEnd.column();
+ return {Start, End};
+}
+
} // namespace
-llvm::Expected<Location> indexToLSPLocation(const SymbolLocation &Loc,
+llvm::Expected<Location> indexToLSPLocation(const SymbolNameLocation &Loc,
llvm::StringRef TUPath) {
auto Path = URI::resolve(Loc.FileURI, TUPath);
if (!Path)
@@ -64,17 +74,21 @@ llvm::Expected<Location> indexToLSPLocation(const SymbolLocation &Loc,
Path.takeError());
Location L;
L.uri = URIForFile::canonicalize(*Path, TUPath);
- Position Start, End;
- Start.line = Loc.Start.line();
- Start.character = Loc.Start.column();
- End.line = Loc.End.line();
- End.character = Loc.End.column();
- L.range = {Start, End};
+ L.range = indexToLSPRange(Loc.Start, Loc.End);
return L;
}
-llvm::Expected<Location> symbolToLocation(const Symbol &Sym,
- llvm::StringRef TUPath) {
+llvm::Expected<std::pair<Location, Range>>
+indexToLSPLocation(const SymbolDeclDefLocation &Loc, StringRef TUPath) {
+ auto L = indexToLSPLocation(Loc.NameLocation, TUPath);
+ if (!L)
+ return L.takeError();
+ return std::make_pair(L.get(),
+ indexToLSPRange(Loc.DeclDefStart, Loc.DeclDefEnd));
+}
+
+llvm::Expected<std::pair<Location, Range>>
+symbolToLocation(const Symbol &Sym, llvm::StringRef TUPath) {
// Prefer the definition over e.g. a function declaration in a header
return indexToLSPLocation(
Sym.Definition ? Sym.Definition : Sym.CanonicalDeclaration, TUPath);
@@ -152,7 +166,7 @@ getWorkspaceSymbols(llvm::StringRef Query, int Limit,
SymbolInformation Info;
Info.name = (Sym.Name + Sym.TemplateSpecializationArgs).str();
Info.kind = indexSymbolKindToSymbolKind(Sym.SymInfo.Kind);
- Info.location = *Loc;
+ Info.location = Loc->first;
Scope.consume_back("::");
Info.containerName = Scope.str();
diff --git a/clang-tools-extra/clangd/FindSymbols.h b/clang-tools-extra/clangd/FindSymbols.h
index 5fb116b13d1136..29fe82d8aaa867 100644
--- a/clang-tools-extra/clangd/FindSymbols.h
+++ b/clang-tools-extra/clangd/FindSymbols.h
@@ -22,12 +22,14 @@ class ParsedAST;
class SymbolIndex;
/// Helper function for deriving an LSP Location from an index SymbolLocation.
-llvm::Expected<Location> indexToLSPLocation(const SymbolLocation &Loc,
+llvm::Expected<Location> indexToLSPLocation(const SymbolNameLocation &Loc,
llvm::StringRef TUPath);
+llvm::Expected<std::pair<Location, Range>>
+indexToLSPLocation(const SymbolDeclDefLocation &Loc, llvm::StringRef TUPath);
/// Helper function for deriving an LSP Location for a Symbol.
-llvm::Expected<Location> symbolToLocation(const Symbol &Sym,
- llvm::StringRef TUPath);
+llvm::Expected<std::pair<Location, Range>>
+symbolToLocation(const Symbol &Sym, llvm::StringRef TUPath);
/// Searches for the symbols matching \p Query. The syntax of \p Query can be
/// the non-qualified name or fully qualified of a symbol. For example,
diff --git a/clang-tools-extra/clangd/HeaderSourceSwitch.cpp b/clang-tools-extra/clangd/HeaderSourceSwitch.cpp
index 2351858cc62972..c191e79b1962d3 100644
--- a/clang-tools-extra/clangd/HeaderSourceSwitch.cpp
+++ b/clang-tools-extra/clangd/HeaderSourceSwitch.cpp
@@ -95,9 +95,9 @@ std::optional<Path> getCorrespondingHeaderOrSource(PathRef OriginalFile,
bool IsHeader = isHeaderFile(OriginalFile, AST.getLangOpts());
Index->lookup(Request, [&](const Symbol &Sym) {
if (IsHeader)
- AwardTarget(Sym.Definition.FileURI);
+ AwardTarget(Sym.Definition.fileURI());
else
- AwardTarget(Sym.CanonicalDeclaration.FileURI);
+ AwardTarget(Sym.CanonicalDeclaration.fileURI());
});
// FIXME: our index doesn't have any interesting information (this could be
// that the background-index is not finished), we should use the decl/def
diff --git a/clang-tools-extra/clangd/IncludeFixer.cpp b/clang-tools-extra/clangd/IncludeFixer.cpp
index fadd1105691fc0..f146bb3ba1b161 100644
--- a/clang-tools-extra/clangd/IncludeFixer.cpp
+++ b/clang-tools-extra/clangd/IncludeFixer.cpp
@@ -289,7 +289,7 @@ std::vector<Fix> IncludeFixer::fixIncompleteType(const Type &T) const {
if (!Syms.empty()) {
auto &Matched = *Syms.begin();
if (!Matched.IncludeHeaders.empty() && Matched.Definition &&
- Matched.CanonicalDeclaration.FileURI == Matched.Definition.FileURI)
+ Matched.CanonicalDeclaration.fileURI() == Matched.Definition.fileURI())
Fixes = fixesForSymbols(Syms);
}
return Fixes;
@@ -299,7 +299,7 @@ std::vector<Fix> IncludeFixer::fixesForSymbols(const SymbolSlab &Syms) const {
auto Inserted = [&](const Symbol &Sym, llvm::StringRef Header)
-> llvm::Expected<std::pair<std::string, bool>> {
auto ResolvedDeclaring =
- URI::resolve(Sym.CanonicalDeclaration.FileURI, File);
+ URI::resolve(Sym.CanonicalDeclaration.fileURI(), File);
if (!ResolvedDeclaring)
return ResolvedDeclaring.takeError();
auto ResolvedInserted = toHeaderFile(Header, File);
@@ -616,7 +616,7 @@ IncludeFixer::lookupCached(const SymbolID &ID) const {
if (!Syms.empty()) {
auto &Matched = *Syms.begin();
if (!Matched.IncludeHeaders.empty() && Matched.Definition &&
- Matched.CanonicalDeclaration.FileURI == Matched.Definition.FileURI)
+ Matched.CanonicalDeclaration.fileURI() == Matched.Definition.fileURI())
Fixes = fixesForSymbols(Syms);
}
auto E = LookupCache.try_emplace(ID, std::move(Syms));
diff --git a/clang-tools-extra/clangd/Quality.cpp b/clang-tools-extra/clangd/Quality.cpp
index c1ab63fb22f61e..1154a426740209 100644
--- a/clang-tools-extra/clangd/Quality.cpp
+++ b/clang-tools-extra/clangd/Quality.cpp
@@ -281,7 +281,7 @@ computeScope(const NamedDecl *D) {
}
void SymbolRelevanceSignals::merge(const Symbol &IndexResult) {
- SymbolURI = IndexResult.CanonicalDeclaration.FileURI;
+ SymbolURI = IndexResult.CanonicalDeclaration.fileURI();
SymbolScope = IndexResult.Scope;
IsInstanceMember |= isInstanceMember(IndexResult.SymInfo);
if (!(IndexResult.Flags & Symbol::VisibleOutsideFile)) {
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index 8d5ab2e491a406..d8234250a2ad54 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -114,14 +114,14 @@ const NamedDecl *getDefinition(const NamedDecl *D) {
return nullptr; // except cases above
}
-void logIfOverflow(const SymbolLocation &Loc) {
+void logIfOverflow(const SymbolNameLocation &Loc) {
if (Loc.Start.hasOverflow() || Loc.End.hasOverflow())
log("Possible overflow in symbol location: {0}", Loc);
}
// Convert a SymbolLocation to LSP's Location.
// TUPath is used to resolve the path of URI.
-std::optional<Location> toLSPLocation(const SymbolLocation &Loc,
+std::optional<Location> toLSPLocation(const SymbolNameLocation &Loc,
llvm::StringRef TUPath) {
if (!Loc)
return std::nullopt;
@@ -134,8 +134,9 @@ std::optional<Location> toLSPLocation(const SymbolLocation &Loc,
return *LSPLoc;
}
-SymbolLocation toIndexLocation(const Location &Loc, std::string &URIStorage) {
- SymbolLocation SymLoc;
+SymbolNameLocation toIndexLocation(const Location &Loc,
+ std::string &URIStorage) {
+ SymbolNameLocation SymLoc;
URIStorage = Loc.uri.uri();
SymLoc.FileURI = URIStorage.c_str();
SymLoc.Start.setLine(Loc.range.start.line);
@@ -146,17 +147,17 @@ SymbolLocation toIndexLocation(const Location &Loc, std::string &URIStorage) {
}
// Returns the preferred location between an AST location and an index location.
-SymbolLocation getPreferredLocation(const Location &ASTLoc,
- const SymbolLocation &IdxLoc,
- std::string &Scratch) {
+SymbolNameLocation getPreferredLocation(const Location &ASTLoc,
+ const SymbolNameLocation &IdxLoc,
+ std::string &Scratch) {
// Also use a mock symbol for the index location so that other fields (e.g.
// definition) are not factored into the preference.
Symbol ASTSym, IdxSym;
ASTSym.ID = IdxSym.ID = SymbolID("mock_symbol_id");
- ASTSym.CanonicalDeclaration = toIndexLocation(ASTLoc, Scratch);
- IdxSym.CanonicalDeclaration = IdxLoc;
+ ASTSym.CanonicalDeclaration.NameLocation = toIndexLocation(ASTLoc, Scratch);
+ IdxSym.CanonicalDeclaration.NameLocation = IdxLoc;
auto Merged = mergeSymbol(ASTSym, IdxSym);
- return Merged.CanonicalDeclaration;
+ return Merged.CanonicalDeclaration.NameLocation;
}
std::vector<std::pair<const NamedDecl *, DeclRelationSet>>
@@ -309,8 +310,8 @@ std::vector<LocatedSymbol> findImplementors(llvm::DenseSet<SymbolID> IDs,
Req.Subjects = std::move(IDs);
std::vector<LocatedSymbol> Results;
Index->relations(Req, [&](const SymbolID &Subject, const Symbol &Object) {
- auto DeclLoc =
- indexToLSPLocation(Object.CanonicalDeclaration, MainFilePath);
+ auto DeclLoc = indexToLSPLocation(Object.CanonicalDeclaration.NameLocation,
+ MainFilePath);
if (!DeclLoc) {
elog("Find overrides: {0}", DeclLoc.takeError());
return;
@@ -318,7 +319,8 @@ std::vector<LocatedSymbol> findImplementors(llvm::DenseSet<SymbolID> IDs,
Results.emplace_back();
Results.back().Name = Object.Name.str();
Results.back().PreferredDeclaration = *DeclLoc;
- auto DefLoc = indexToLSPLocation(Object.Definition, MainFilePath);
+ auto DefLoc =
+ indexToLSPLocation(Object.Definition.NameLocation, MainFilePath);
if (!DefLoc) {
elog("Failed to convert location: {0}", DefLoc.takeError());
return;
@@ -350,23 +352,26 @@ void enhanceLocatedSymbolsFromIndex(llvm::MutableArrayRef<LocatedSymbol> Result,
if (R.Definition) { // from AST
// Special case: if the AST yielded a definition, then it may not be
// the right *declaration*. Prefer the one from the index.
- if (auto Loc = toLSPLocation(Sym.CanonicalDeclaration, MainFilePath))
+ if (auto Loc = toLSPLocation(Sym.CanonicalDeclaration.NameLocation,
+ MainFilePath))
R.PreferredDeclaration = *Loc;
// We might still prefer the definition from the index, e.g. for
// generated symbols.
if (auto Loc = toLSPLocation(
- getPreferredLocation(*R.Definition, Sym.Definition, Scratch),
+ getPreferredLocation(*R.Definition, Sym.Definition.NameLocation,
+ Scratch),
MainFilePath))
R.Definition = *Loc;
} else {
- R.Definition = toLSPLocation(Sym.Definition, MainFilePath);
+ R.Definition = toLSPLocation(Sym.Definition.NameLocation, MainFilePath);
// Use merge logic to choose AST or index declaration.
- if (auto Loc = toLSPLocation(
- getPreferredLocation(R.PreferredDeclaration,
- Sym.CanonicalDeclaration, Scratch),
- MainFilePath))
+ if (auto Loc =
+ toLSPLocation(getPreferredLocation(
+ R.PreferredDeclaration,
+ Sym.CanonicalDeclaration.NameLocation, Scratch),
+ MainFilePath))
R.PreferredDeclaration = *Loc;
}
});
@@ -592,7 +597,7 @@ std::vector<LocatedSymbol> locateSymbolTextually(const SpelledWord &Word,
return;
auto MaybeDeclLoc =
- indexToLSPLocation(Sym.CanonicalDeclaration, MainFilePath);
+ indexToLSPLocation(Sym.CanonicalDeclaration.NameLocation, MainFilePath);
if (!MaybeDeclLoc) {
log("locateSymbolNamedTextuallyAt: {0}", MaybeDeclLoc.takeError());
return;
@@ -602,7 +607,8 @@ std::vector<LocatedSymbol> locateSymbolTextually(const SpelledWord &Word,
Located.Name = (Sym.Name + Sym.TemplateSpecializationArgs).str();
Located.ID = Sym.ID;
if (Sym.Definition) {
- auto MaybeDefLoc = indexToLSPLocation(Sym.Definition, MainFilePath);
+ auto MaybeDefLoc =
+ indexToLSPLocation(Sym.Definition.NameLocation, MainFilePath);
if (!MaybeDefLoc) {
log("locateSymbolNamedTextuallyAt: {0}", MaybeDefLoc.takeError());
return;
@@ -1481,9 +1487,10 @@ ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
Results.HasMore = true;
return;
}
- const auto LSPLocDecl =
- toLSPLocation(Object.CanonicalDeclaration, MainFilePath);
- const auto LSPLocDef = toLSPLocation(Object.Definition, MainFilePath);
+ const auto LSPLocDecl = toLSPLocation(
+ Object.CanonicalDeclaration.NameLocation, MainFilePath);
+ const auto LSPLocDef =
+ toLSPLocation(Object.Definition.NameLocation, MainFilePath);
if (LSPLocDecl && LSPLocDecl != LSPLocDef) {
ReferencesResult::Reference Result;
Result.Loc = {std::move(*LSPLocDecl), std::nullopt};
@@ -1742,11 +1749,9 @@ static std::optional<HierarchyItem> symbolToHierarchyItem(const Symbol &S,
HI.name = std::string(S.Name);
HI.detail = (S.Scope + S.Name).str();
HI.kind = indexSymbolKindToSymbolKind(S.SymInfo.Kind);
- HI.selectionRange = Loc->range;
- // FIXME: Populate 'range' correctly
- // (https://github.com/clangd/clangd/issues/59).
- HI.range = HI.selectionRange;
- HI.uri = Loc->uri;
+ HI.selectionRange = Loc->first.range;
+ HI.range = Loc->second;
+ HI.uri = Loc->first.uri;
return HI;
}
diff --git a/clang-tools-extra/clangd/index/FileIndex.cpp b/clang-tools-extra/clangd/index/FileIndex.cpp
index aa573e312a756a..407f1b2f350ab6 100644
--- a/clang-tools-extra/clangd/index/FileIndex.cpp
+++ b/clang-tools-extra/clangd/index/FileIndex.cpp
@@ -132,13 +132,13 @@ FileShardedIndex::FileShardedIndex(IndexFileIn Input)
// Attribute each Symbol to both their declaration and definition locations.
if (Index.Symbols) {
for (const auto &S : *Index.Symbols) {
- auto It = Shards.try_emplace(S.CanonicalDeclaration.FileURI);
+ auto It = Shards.try_emplace(S.CanonicalDeclaration.fileURI());
It.first->getValue().Symbols.insert(&S);
SymbolIDToFile[S.ID] = &It.first->getValue();
// Only bother if definition file is different than declaration file.
if (S.Definition &&
- S.Definition.FileURI != S.CanonicalDeclaration.FileURI) {
- auto It = Shards.try_emplace(S.Definition.FileURI);
+ S.Definition.fileURI() != S.CanonicalDeclaration.fileURI()) {
+ auto It = Shards.try_emplace(S.Definition.fileURI());
It.first->getValue().Symbols.insert(&S);
}
}
diff --git a/clang-tools-extra/clangd/index/Index.h b/clang-tools-extra/clangd/index/Index.h
index a193b1a191216a..d9de6ec7d29af0 100644
--- a/clang-tools-extra/clangd/index/Index.h
+++ b/clang-tools-extra/clangd/index/Index.h
@@ -99,7 +99,7 @@ struct RelationsRequest {
struct ContainedRefsResult {
/// The source location where the symbol is named.
- SymbolLocation Location;
+ SymbolNameLocation Location;
RefKind Kind = RefKind::Unknown;
/// The ID of the symbol which is referred to
SymbolID Symbol;
diff --git a/clang-tools-extra/clangd/index/Merge.cpp b/clang-tools-extra/clangd/index/Merge.cpp
index aecca38a885b66..2fd9aa1bf785c9 100644
--- a/clang-tools-extra/clangd/index/Merge.cpp
+++ b/clang-tools-extra/clangd/index/Merge.cpp
@@ -26,7 +26,7 @@ bool isIndexAuthoritative(const SymbolIndex::IndexedFiles &Index,
// We expect the definition to see the canonical declaration, so it seems to
// be enough to check only the definition if it exists.
const char *OwningFile =
- S.Definition ? S.Definition.FileURI : S.CanonicalDeclaration.FileURI;
+ S.Definition ? S.Definition.fileURI() : S.CanonicalDeclaration.fileURI();
return (Index(OwningFile) & IndexContents::Symbols) != IndexContents::None;
}
} // namespace
@@ -223,15 +223,16 @@ void MergedIndex::relations(
// Returns true if \p L is (strictly) preferred to \p R (e.g. by file paths). If
// neither is preferred, this returns false.
-static bool prefer(const SymbolLocation &L, const SymbolLocation &R) {
+static bool prefer(const SymbolDeclDefLocation &L,
+ const SymbolDeclDefLocation &R) {
if (!L)
return false;
if (!R)
return true;
- auto HasCodeGenSuffix = [](const SymbolLocation &Loc) {
+ auto HasCodeGenSuffix = [](const SymbolDeclDefLocation &Loc) {
constexpr static const char *CodegenSuffixes[] = {".proto"};
return llvm::any_of(CodegenSuffixes, [&](llvm::StringRef Suffix) {
- return llvm::StringRef(Loc.FileURI).ends_with(Suffix);
+ return llvm::StringRef(Loc.fileURI()).ends_with(Suffix);
});
};
return HasCodeGenSuffix(L) && !HasCodeGenSuffix(R);
@@ -245,9 +246,9 @@ Symbol mergeSymbol(const Symbol &L, const Symbol &R) {
bool PreferR = R.Definition && !L.Definition;
// Merge include headers only if both have definitions or both have no
// definition; otherwise, only accumulate references of common includes.
- assert(L.Definition.FileURI && R.Definition.FileURI);
+ assert(L.Definition.fileURI() && R.Definition.fileURI());
bool MergeIncludes =
- bool(*L.Definition.FileURI) == bool(*R.Definition.FileURI);
+ bool(*L.Definition.fileURI()) == bool(*R.Definition.fileURI());
Symbol S = PreferR ? R : L; // The target symbol we're merging into.
const Symbol &O = PreferR ? L : R; // The "other" less-preferred symbol.
diff --git a/clang-tools-extra/clangd/index/Ref.h b/clang-tools-extra/clangd/index/Ref.h
index 870f77f56e6cb3..3557d32425d652 100644
--- a/clang-tools-extra/clangd/index/Ref.h
+++ b/clang-tools-extra/clangd/index/Ref.h
@@ -18,6 +18,7 @@
#include <cstdint>
#include <set>
#include <utility>
+#include <variant>
namespace clang {
namespace clangd {
@@ -87,7 +88,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &, RefKind);
/// WARNING: Location does not own the underlying data - Copies are shallow.
struct Ref {
/// The source location where the symbol is named.
- SymbolLocation Location;
+ SymbolNameLocation Location;
RefKind Kind = RefKind::Unknown;
/// The ID of the symbol whose definition contains this reference.
/// For example, for a reference inside a function body, this would
@@ -185,12 +186,8 @@ template <> struct DenseMapInfo<clang::clangd::RefSlab::Builder::Entry> {
Val.Reference.Location.Start.rep(), Val.Reference.Location.End.rep());
}
static bool isEqual(const Entry &LHS, const Entry &RHS) {
- return std::tie(LHS.Symbol, LHS.Reference.Location.FileURI,
- LHS.Reference.Kind) ==
- std::tie(RHS.Symbol, RHS.Reference.Location.FileURI,
- RHS.Reference.Kind) &&
- LHS.Reference.Location.Start == RHS.Reference.Location.Start &&
- LHS.Reference.Location.End == RHS.Reference.Location.End;
+ return std::tie(LHS.Symbol, LHS.Reference) ==
+ std::tie(RHS.Symbol, RHS.Reference);
}
};
} // namespace llvm
diff --git a/clang-tools-extra/clangd/index/Serialization.cpp b/clang-tools-extra/clangd/index/Serialization.cpp
index f03839599612c7..e7b64b789c05df 100644
--- a/clang-tools-extra/clangd/index/Serialization.cpp
+++ b/clang-tools-extra/clangd/index/Serialization.cpp
@@ -263,7 +263,7 @@ llvm::Expected<StringTableIn> readStringTable(llvm::StringRef Data) {
// - enums encode as the underlying type
// - most numbers encode as varint
-void writeLocation(const SymbolLocation &Loc, const StringTableOut &Strings,
+void writeLocation(const SymbolNameLocation &Loc, const StringTableOut &Strings,
llvm::raw_ostream &OS) {
writeVar(Strings.index(Loc.FileURI), OS);
for (const auto &Endpoint : {Loc.Start, Loc.End}) {
@@ -272,9 +272,9 @@ void writeLocation(const SymbolLocation &Loc, const StringTableOut &Strings,
}
}
-SymbolLocation readLocation(Reader &Data,
- llvm::ArrayRef<llvm::StringRef> Strings) {
- SymbolLocation Loc;
+SymbolNameLocation readNameLocation(Reader &Data,
+ llvm::ArrayRef<llvm::StringRef> Strings) {
+ SymbolNameLocation Loc;
Loc.FileURI = Data.consumeString(Strings).data();
for (auto *Endpoint : {&Loc.Start, &Loc.End}) {
Endpoint->setLine(Data.consumeVar());
@@ -283,6 +283,26 @@ SymbolLocation readLocation(Reader &Data,
return Loc;
}
+void writeLocation(const SymbolDeclDefLocation &Loc,
+ const StringTableOut &Strings, llvm::raw_ostream &OS) {
+ writeLocation(Loc.NameLocation, Strings, OS);
+ for (const auto &Endpoint : {Loc.DeclDefStart, Loc.DeclDefEnd}) {
+ writeVar(Endpoint.line(), OS);
+ writeVar(Endpoint.column(), OS);
+ }
+}
+
+SymbolDeclDefLocation
+readDeclDefLocation(Reader &Data, llvm::ArrayRef<llvm::StringRef> Strings) {
+ SymbolDeclDefLocation Loc;
+ Loc.NameLocation = readNameLocation(Data, Strings);
+ for (auto *Endpoint : {&Loc.DeclDefStart, &Loc.DeclDefEnd}) {
+ Endpoint->setLine(Data.consumeVar());
+ Endpoint->setColumn(Data.consumeVar());
+ }
+ return Loc;
+}
+
IncludeGraphNode readIncludeGraphNode(Reader &Data,
llvm::ArrayRef<llvm::StringRef> Strings) {
IncludeGraphNode IGN;
@@ -347,8 +367,8 @@ Symbol readSymbol(Reader &Data, llvm::ArrayRef<llvm::StringRef> Strings,
Sym.Name = Data.consumeString(Strings);
Sym.Scope = Data.consumeString(Strings);
Sym.TemplateSpecializationArgs = Data.consumeString(Strings);
- Sym.Definition = readLocation(Data, Strings);
- Sym.CanonicalDeclaration = readLocation(Data, Strings);
+ Sym.Definition = readDeclDefLocation(Data, Strings);
+ Sym.CanonicalDeclaration = readDeclDefLocation(Data, Strings);
Sym.References = Data.consumeVar();
Sym.Flags = static_cast<Symbol::SymbolFlag>(Data.consume8());
Sym.Origin = Origin;
@@ -394,7 +414,7 @@ readRefs(Reader &Data, llvm::ArrayRef<llvm::StringRef> Strings) {
return Result;
for (auto &Ref : Result.second) {
Ref.Kind = static_cast<RefKind>(Data.consume8());
- Ref.Location = readLocation(Data, Strings);
+ Ref.Location = readNameLocation(Data, Strings);
Ref.Container = Data.consumeID();
}
return Result;
diff --git a/clang-tools-extra/clangd/index/StdLib.cpp b/clang-tools-extra/clangd/index/StdLib.cpp
index d34838a45048de..f3d7e9ff756e8f 100644
--- a/clang-tools-extra/clangd/index/StdLib.cpp
+++ b/clang-tools-extra/clangd/index/StdLib.cpp
@@ -155,12 +155,12 @@ SymbolSlab filter(SymbolSlab Slab, const StdLibLocation &Loc) {
for (const Symbol &S : Slab) {
if (!S.IncludeHeaders.empty() &&
StandardHeaders.contains(S.IncludeHeaders.front().IncludeHeader)) {
- GoodHeader[S.CanonicalDeclaration.FileURI] = true;
- GoodHeader[S.Definition.FileURI] = true;
+ GoodHeader[S.CanonicalDeclaration.fileURI()] = true;
+ GoodHeader[S.Definition.fileURI()] = true;
continue;
}
for (const char *URI :
- {S.CanonicalDeclaration.FileURI, S.Definition.FileURI}) {
+ {S.CanonicalDeclaration.fileURI(), S.Definition.fileURI()}) {
auto R = GoodHeader.try_emplace(URI, false);
if (R.second) {
R.first->second = llvm::any_of(
@@ -180,10 +180,10 @@ SymbolSlab filter(SymbolSlab Slab, const StdLibLocation &Loc) {
auto IsGoodHeader = [&](const char *C) { return *C && GoodHeader.lookup(C); };
for (const Symbol &S : Slab) {
- if (!(IsGoodHeader(S.CanonicalDeclaration.FileURI) ||
- IsGoodHeader(S.Definition.FileURI))) {
+ if (!(IsGoodHeader(S.CanonicalDeclaration.fileURI()) ||
+ IsGoodHeader(S.Definition.fileURI()))) {
dlog("Ignoring wrong-header symbol {0}{1} in {2}", S.Scope, S.Name,
- S.CanonicalDeclaration.FileURI);
+ S.CanonicalDeclaration.fileURI());
continue;
}
Result.insert(S);
diff --git a/clang-tools-extra/clangd/index/Symbol.h b/clang-tools-extra/clangd/index/Symbol.h
index 62c47ddfc5758d..09275321445d13 100644
--- a/clang-tools-extra/clangd/index/Symbol.h
+++ b/clang-tools-extra/clangd/index/Symbol.h
@@ -47,7 +47,7 @@ struct Symbol {
llvm::StringRef Scope;
/// The location of the symbol's definition, if one was found.
/// This just covers the symbol name (e.g. without class/function body).
- SymbolLocation Definition;
+ SymbolDeclDefLocation Definition;
/// The location of the preferred declaration of the symbol.
/// This just covers the symbol name.
/// This may be the same as Definition.
@@ -56,7 +56,7 @@ struct Symbol {
/// * For classes, the canonical declaration should be the definition.
/// * For non-inline functions, the canonical declaration typically appears
/// in the ".h" file corresponding to the definition.
- SymbolLocation CanonicalDeclaration;
+ SymbolDeclDefLocation CanonicalDeclaration;
/// The number of translation units that reference this symbol from their main
/// file. This number is only meaningful if aggregated in an index.
unsigned References = 0;
@@ -183,8 +183,8 @@ template <typename Callback> void visitStrings(Symbol &S, const Callback &CB) {
assert(!S.data()[S.size()] && "Visited StringRef must be null-terminated");
P = S.data();
};
- RawCharPointerCB(S.CanonicalDeclaration.FileURI);
- RawCharPointerCB(S.Definition.FileURI);
+ RawCharPointerCB(S.CanonicalDeclaration.NameLocation.FileURI);
+ RawCharPointerCB(S.Definition.NameLocation.FileURI);
for (auto &Include : S.IncludeHeaders)
CB(Include.IncludeHeader);
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp
index 81125dbb1aeafc..352d5701d74547 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.cpp
+++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp
@@ -160,18 +160,23 @@ Symbol::IncludeDirective shouldCollectIncludePath(index::SymbolKind Kind) {
}
}
+SymbolPosition sourceLocToSymbolPosition(SourceLocation Loc,
+ const SourceManager &SM,
+ const LangOptions &LangOpts) {
+ auto LSPLoc = sourceLocToPosition(SM, Loc);
+ SymbolPosition Pos;
+ Pos.setLine(LSPLoc.line);
+ Pos.setColumn(LSPLoc.character);
+ return Pos;
+}
+
// Return the symbol range of the token at \p TokLoc.
-std::pair<SymbolLocation::Position, SymbolLocation::Position>
+std::pair<SymbolPosition, SymbolPosition>
getTokenRange(SourceLocation TokLoc, const SourceManager &SM,
const LangOptions &LangOpts) {
- auto CreatePosition = [&SM](SourceLocation Loc) {
- auto LSPLoc = sourceLocToPosition(SM, Loc);
- SymbolLocation::Position Pos;
- Pos.setLine(LSPLoc.line);
- Pos.setColumn(LSPLoc.character);
- return Pos;
+ auto CreatePosition = [&](SourceLocation Loc) {
+ return sourceLocToSymbolPosition(Loc, SM, LangOpts);
};
-
auto TokenLength = clang::Lexer::MeasureTokenLength(TokLoc, SM, LangOpts);
return {CreatePosition(TokLoc),
CreatePosition(TokLoc.getLocWithOffset(TokenLength))};
@@ -474,19 +479,52 @@ class SymbolCollector::HeaderFileURICache {
}
};
-// Return the symbol location of the token at \p TokLoc.
-std::optional<SymbolLocation>
-SymbolCollector::getTokenLocation(SourceLocation TokLoc) {
+// Return the location of the given symbol.
+std::optional<SymbolDeclDefLocation> SymbolCollector::getSymbolLocation(
+ const std::variant<const Decl *, const MacroInfo *> &Symbol) {
const auto &SM = ASTCtx->getSourceManager();
- const auto FE = SM.getFileEntryRefForID(SM.getFileID(TokLoc));
+ const MacroInfo *MI = nullptr;
+ const Decl *D = nullptr;
+ if (auto MIP = std::get_if<const MacroInfo *>(&Symbol))
+ MI = *MIP;
+ else
+ D = std::get<const Decl *>(Symbol);
+ const SourceLocation NameLoc =
+ MI ? MI->getDefinitionLoc() : nameLocation(*D, SM);
+ const auto FE = SM.getFileEntryRefForID(SM.getFileID(NameLoc));
if (!FE)
return std::nullopt;
- SymbolLocation Result;
- Result.FileURI = HeaderFileURIs->toURI(*FE).c_str();
- auto Range = getTokenRange(TokLoc, SM, ASTCtx->getLangOpts());
- Result.Start = Range.first;
- Result.End = Range.second;
+ SymbolDeclDefLocation Result;
+ Result.NameLocation.FileURI = HeaderFileURIs->toURI(*FE).c_str();
+ auto NameRange = getTokenRange(NameLoc, SM, ASTCtx->getLangOpts());
+ Result.NameLocation.Start = NameRange.first;
+ Result.NameLocation.End = NameRange.second;
+
+ if (MI) {
+ Result.DeclDefStart = Result.NameLocation.Start;
+ Result.DeclDefEnd = sourceLocToSymbolPosition(MI->getDefinitionEndLoc(), SM,
+ ASTCtx->getLangOpts());
+ } else {
+ // TODO: Comments.
+ Result.DeclDefStart =
+ sourceLocToSymbolPosition(D->getBeginLoc(), SM, ASTCtx->getLangOpts());
+ SourceLocation EndLoc = D->getEndLoc();
+ bool ExtendEndLoc = false;
+ if (llvm::isa<RecordDecl>(D)) {
+ ExtendEndLoc = true;
+ } else if (auto *FD = llvm::dyn_cast_or_null<FunctionDecl>(D);
+ FD && !FD->hasBody()) {
+ ExtendEndLoc = true;
+ }
+ if (ExtendEndLoc) {
+ auto NextTok = Lexer::findNextToken(EndLoc, SM, ASTCtx->getLangOpts());
+ if (NextTok && NextTok->is(tok::semi))
+ EndLoc = NextTok->getEndLoc();
+ }
+ Result.DeclDefEnd =
+ sourceLocToSymbolPosition(EndLoc, SM, ASTCtx->getLangOpts());
+ }
return Result;
}
@@ -650,6 +688,7 @@ bool SymbolCollector::handleDeclOccurrence(
processRelations(*ND, ID, Relations);
bool CollectRef = static_cast<bool>(Opts.RefFilter & toRefKind(Roles));
+
// Unlike other fields, e.g. Symbols (which use spelling locations), we use
// file locations for references (as it aligns the behavior of clangd's
// AST-based xref).
@@ -719,6 +758,14 @@ void SymbolCollector::handleMacros(const MainFileMacros &MacroRefsToIndex) {
R.Kind = IsDefinition ? RefKind::Definition : RefKind::Reference;
Refs.insert(IDToRefs.first, R);
if (IsDefinition) {
+ SymbolDeclDefLocation DeclDefLoc;
+ DeclDefLoc.NameLocation = R.Location;
+
+ // FIXME: How does this function relate to handleMacroOccurrence(),
+ // where we retrieve the full definition location?
+ DeclDefLoc.DeclDefStart = R.Location.Start;
+ DeclDefLoc.DeclDefEnd = R.Location.End;
+
Symbol S;
S.ID = IDToRefs.first;
auto StartLoc = cantFail(sourceLocationInMainFile(SM, Range.start));
@@ -729,7 +776,7 @@ void SymbolCollector::handleMacros(const MainFileMacros &MacroRefsToIndex) {
S.SymInfo.Properties = index::SymbolPropertySet();
S.SymInfo.Lang = index::SymbolLanguage::C;
S.Origin = Opts.Origin;
- S.CanonicalDeclaration = R.Location;
+ S.CanonicalDeclaration = DeclDefLoc;
// Make the macro visible for code completion if main file is an
// include-able header.
if (!HeaderFileURIs->getIncludeHeader(SM.getMainFileID()).empty()) {
@@ -818,7 +865,7 @@ bool SymbolCollector::handleMacroOccurrence(const IdentifierInfo *Name,
S.Origin = Opts.Origin;
// FIXME: use the result to filter out symbols.
shouldIndexFile(SM.getFileID(Loc));
- if (auto DeclLoc = getTokenLocation(DefLoc))
+ if (auto DeclLoc = getSymbolLocation(MI))
S.CanonicalDeclaration = *DeclLoc;
CodeCompletionResult SymbolCompletion(Name);
@@ -1059,7 +1106,7 @@ const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND, SymbolID ID,
// FIXME: use the result to filter out symbols.
auto FID = SM.getFileID(Loc);
shouldIndexFile(FID);
- if (auto DeclLoc = getTokenLocation(Loc))
+ if (auto DeclLoc = getSymbolLocation(&ND))
S.CanonicalDeclaration = *DeclLoc;
S.Origin = Opts.Origin;
@@ -1127,7 +1174,7 @@ void SymbolCollector::addDefinition(const NamedDecl &ND, const Symbol &DeclSym,
const auto &SM = ND.getASTContext().getSourceManager();
auto Loc = nameLocation(ND, SM);
shouldIndexFile(SM.getFileID(Loc));
- auto DefLoc = getTokenLocation(Loc);
+ auto DefLoc = getSymbolLocation(&ND);
// If we saw some forward declaration, we end up copying the symbol.
// This is not ideal, but avoids duplicating the "is this a definition" check
// in clang::index. We should only see one definition.
diff --git a/clang-tools-extra/clangd/index/SymbolCollector.h b/clang-tools-extra/clangd/index/SymbolCollector.h
index e9eb27fd0f6648..9ae9a6fb5a2ce5 100644
--- a/clang-tools-extra/clangd/index/SymbolCollector.h
+++ b/clang-tools-extra/clangd/index/SymbolCollector.h
@@ -166,7 +166,8 @@ class SymbolCollector : public index::IndexDataConsumer {
void processRelations(const NamedDecl &ND, const SymbolID &ID,
ArrayRef<index::SymbolRelation> Relations);
- std::optional<SymbolLocation> getTokenLocation(SourceLocation TokLoc);
+ std::optional<SymbolDeclDefLocation> getSymbolLocation(
+ const std::variant<const Decl *, const MacroInfo *> &Symbol);
std::optional<std::string> getIncludeHeader(const Symbol &S, FileID);
diff --git a/clang-tools-extra/clangd/index/SymbolLocation.cpp b/clang-tools-extra/clangd/index/SymbolLocation.cpp
index 61da267b93ce5b..b3306a4120048b 100644
--- a/clang-tools-extra/clangd/index/SymbolLocation.cpp
+++ b/clang-tools-extra/clangd/index/SymbolLocation.cpp
@@ -11,21 +11,22 @@
namespace clang {
namespace clangd {
-constexpr uint32_t SymbolLocation::Position::MaxLine;
-constexpr uint32_t SymbolLocation::Position::MaxColumn;
+constexpr uint32_t SymbolPosition::MaxLine;
+constexpr uint32_t SymbolPosition::MaxColumn;
-void SymbolLocation::Position::setLine(uint32_t L) {
+void SymbolPosition::setLine(uint32_t L) {
if (L > MaxLine)
L = MaxLine;
LineColumnPacked = (L << ColumnBits) | column();
}
-void SymbolLocation::Position::setColumn(uint32_t Col) {
+void SymbolPosition::setColumn(uint32_t Col) {
if (Col > MaxColumn)
Col = MaxColumn;
LineColumnPacked = (LineColumnPacked & ~MaxColumn) | Col;
}
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolLocation &L) {
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const SymbolNameLocation &L) {
if (!L)
return OS << "(none)";
return OS << L.FileURI << "[" << L.Start.line() << ":" << L.Start.column()
diff --git a/clang-tools-extra/clangd/index/SymbolLocation.h b/clang-tools-extra/clangd/index/SymbolLocation.h
index ea7d605172e477..43f987e5a75c94 100644
--- a/clang-tools-extra/clangd/index/SymbolLocation.h
+++ b/clang-tools-extra/clangd/index/SymbolLocation.h
@@ -16,42 +16,42 @@
namespace clang {
namespace clangd {
-struct SymbolLocation {
- // Specify a position (Line, Column) of symbol. Using Line/Column allows us to
- // build LSP responses without reading the file content.
- //
- // clangd uses the following definitions, which differ slightly from LSP:
- // - Line is the number of newline characters (\n) before the point.
- // - Column is (by default) the number of UTF-16 code between the last \n
- // (or start of file) and the point.
- // If the `offsetEncoding` protocol extension is used to negotiate UTF-8,
- // then it is instead the number of *bytes* since the last \n.
- //
- // Position is encoded into 32 bits to save space.
- // If Line/Column overflow, the value will be their maximum value.
- struct Position {
- Position() = default;
- void setLine(uint32_t Line);
- uint32_t line() const { return LineColumnPacked >> ColumnBits; }
- void setColumn(uint32_t Column);
- uint32_t column() const { return LineColumnPacked & MaxColumn; }
- uint32_t rep() const { return LineColumnPacked; }
-
- bool hasOverflow() const {
- return line() == MaxLine || column() == MaxColumn;
- }
-
- static constexpr unsigned ColumnBits = 12;
- static constexpr uint32_t MaxLine = (1 << (32 - ColumnBits)) - 1;
- static constexpr uint32_t MaxColumn = (1 << ColumnBits) - 1;
-
- private:
- uint32_t LineColumnPacked = 0; // Top 20 bit line, bottom 12 bits column.
- };
+// Specify a position (Line, Column) of symbol. Using Line/Column allows us to
+// build LSP responses without reading the file content.
+//
+// clangd uses the following definitions, which differ slightly from LSP:
+// - Line is the number of newline characters (\n) before the point.
+// - Column is (by default) the number of UTF-16 code between the last \n
+// (or start of file) and the point.
+// If the `offsetEncoding` protocol extension is used to negotiate UTF-8,
+// then it is instead the number of *bytes* since the last \n.
+//
+// Position is encoded into 32 bits to save space.
+// If Line/Column overflow, the value will be their maximum value.
+struct SymbolPosition {
+public:
+ void setLine(uint32_t Line);
+ uint32_t line() const { return LineColumnPacked >> ColumnBits; }
+ void setColumn(uint32_t Column);
+ uint32_t column() const { return LineColumnPacked & MaxColumn; }
+ uint32_t rep() const { return LineColumnPacked; }
+
+ bool hasOverflow() const {
+ return line() == MaxLine || column() == MaxColumn;
+ }
+
+ static constexpr unsigned ColumnBits = 12;
+ static constexpr uint32_t MaxLine = (1 << (32 - ColumnBits)) - 1;
+ static constexpr uint32_t MaxColumn = (1 << ColumnBits) - 1;
+
+private:
+ uint32_t LineColumnPacked = 0; // Top 20 bit line, bottom 12 bits column.
+};
+struct SymbolNameLocation {
/// The symbol range, using half-open range [Start, End).
- Position Start;
- Position End;
+ SymbolPosition Start;
+ SymbolPosition End;
explicit operator bool() const { return !llvm::StringRef(FileURI).empty(); }
@@ -64,30 +64,51 @@ struct SymbolLocation {
const char *FileURI = "";
};
-inline bool operator==(const SymbolLocation::Position &L,
- const SymbolLocation::Position &R) {
+struct SymbolDeclDefLocation {
+ SymbolNameLocation NameLocation;
+
+ /// The range of the full declaration/definition.
+ SymbolPosition DeclDefStart;
+ SymbolPosition DeclDefEnd;
+
+ explicit operator bool() const { return NameLocation.operator bool(); }
+
+ const char *fileURI() const { return NameLocation.FileURI; }
+};
+
+inline bool operator==(const SymbolPosition &L, const SymbolPosition &R) {
return std::make_tuple(L.line(), L.column()) ==
std::make_tuple(R.line(), R.column());
}
-inline bool operator<(const SymbolLocation::Position &L,
- const SymbolLocation::Position &R) {
+inline bool operator<(const SymbolPosition &L, const SymbolPosition &R) {
return std::make_tuple(L.line(), L.column()) <
std::make_tuple(R.line(), R.column());
}
-inline bool operator==(const SymbolLocation &L, const SymbolLocation &R) {
+inline bool operator==(const SymbolNameLocation &L,
+ const SymbolNameLocation &R) {
assert(L.FileURI && R.FileURI);
return !std::strcmp(L.FileURI, R.FileURI) &&
std::tie(L.Start, L.End) == std::tie(R.Start, R.End);
}
-inline bool operator<(const SymbolLocation &L, const SymbolLocation &R) {
+inline bool operator<(const SymbolNameLocation &L,
+ const SymbolNameLocation &R) {
assert(L.FileURI && R.FileURI);
int Cmp = std::strcmp(L.FileURI, R.FileURI);
if (Cmp != 0)
return Cmp < 0;
return std::tie(L.Start, L.End) < std::tie(R.Start, R.End);
}
+inline bool operator==(const SymbolDeclDefLocation &L,
+ const SymbolDeclDefLocation &R) {
+ return std::tie(L.NameLocation, L.DeclDefStart, L.DeclDefEnd) ==
+ std::tie(R.NameLocation, R.DeclDefStart, R.DeclDefEnd);
+}
+inline bool operator<(const SymbolDeclDefLocation &L,
+ const SymbolDeclDefLocation &R) {
+ return L.NameLocation < R.NameLocation;
+}
-llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolLocation &);
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolNameLocation &);
} // namespace clangd
} // namespace clang
diff --git a/clang-tools-extra/clangd/index/YAMLSerialization.cpp b/clang-tools-extra/clangd/index/YAMLSerialization.cpp
index 214a847b5eddb3..a2a2fbba06c41c 100644
--- a/clang-tools-extra/clangd/index/YAMLSerialization.cpp
+++ b/clang-tools-extra/clangd/index/YAMLSerialization.cpp
@@ -84,8 +84,10 @@ using clang::clangd::RefKind;
using clang::clangd::Relation;
using clang::clangd::RelationKind;
using clang::clangd::Symbol;
+using clang::clangd::SymbolDeclDefLocation;
using clang::clangd::SymbolID;
-using clang::clangd::SymbolLocation;
+using clang::clangd::SymbolNameLocation;
+using clang::clangd::SymbolPosition;
using clang::index::SymbolInfo;
using clang::index::SymbolKind;
using clang::index::SymbolLanguage;
@@ -132,15 +134,14 @@ template <> struct MappingTraits<YPosition> {
};
struct NormalizedPosition {
- using Position = clang::clangd::SymbolLocation::Position;
NormalizedPosition(IO &) {}
- NormalizedPosition(IO &, const Position &Pos) {
+ NormalizedPosition(IO &, const SymbolPosition &Pos) {
P.Line = Pos.line();
P.Column = Pos.column();
}
- Position denormalize(IO &) {
- Position Pos;
+ SymbolPosition denormalize(IO &) {
+ SymbolPosition Pos;
Pos.setLine(P.Line);
Pos.setColumn(P.Column);
return Pos;
@@ -163,16 +164,28 @@ struct NormalizedFileURI {
std::string URI;
};
-template <> struct MappingTraits<SymbolLocation> {
- static void mapping(IO &IO, SymbolLocation &Value) {
+template <> struct MappingTraits<SymbolNameLocation> {
+ static void mapping(IO &IO, SymbolNameLocation &Value) {
MappingNormalization<NormalizedFileURI, const char *> NFile(IO,
Value.FileURI);
IO.mapRequired("FileURI", NFile->URI);
- MappingNormalization<NormalizedPosition, SymbolLocation::Position> NStart(
+ MappingNormalization<NormalizedPosition, SymbolPosition> NStart(
IO, Value.Start);
IO.mapRequired("Start", NStart->P);
- MappingNormalization<NormalizedPosition, SymbolLocation::Position> NEnd(
- IO, Value.End);
+ MappingNormalization<NormalizedPosition, SymbolPosition> NEnd(IO,
+ Value.End);
+ IO.mapRequired("End", NEnd->P);
+ }
+};
+
+template <> struct MappingTraits<SymbolDeclDefLocation> {
+ static void mapping(IO &IO, SymbolDeclDefLocation &Value) {
+ IO.mapRequired("NameLoc", Value.NameLocation);
+ MappingNormalization<NormalizedPosition, SymbolPosition> NStart(
+ IO, Value.DeclDefStart);
+ IO.mapRequired("Start", NStart->P);
+ MappingNormalization<NormalizedPosition, SymbolPosition> NEnd(
+ IO, Value.DeclDefEnd);
IO.mapRequired("End", NEnd->P);
}
};
@@ -235,8 +248,8 @@ template <> struct MappingTraits<Symbol> {
IO.mapRequired("Scope", Sym.Scope);
IO.mapRequired("SymInfo", Sym.SymInfo);
IO.mapOptional("CanonicalDeclaration", Sym.CanonicalDeclaration,
- SymbolLocation());
- IO.mapOptional("Definition", Sym.Definition, SymbolLocation());
+ SymbolDeclDefLocation());
+ IO.mapOptional("Definition", Sym.Definition, SymbolDeclDefLocation());
IO.mapOptional("References", Sym.References, 0u);
IO.mapOptional("Flags", NSymbolFlag->Flag);
IO.mapOptional("Signature", Sym.Signature);
diff --git a/clang-tools-extra/clangd/index/dex/Dex.cpp b/clang-tools-extra/clangd/index/dex/Dex.cpp
index 5643ba0c5e4ce8..28b85b961477ae 100644
--- a/clang-tools-extra/clangd/index/dex/Dex.cpp
+++ b/clang-tools-extra/clangd/index/dex/Dex.cpp
@@ -72,9 +72,9 @@ class IndexBuilder {
for (Trigram T : TrigramScratch)
TrigramDocs[T].push_back(D);
ScopeDocs[Sym.Scope].push_back(D);
- if (!llvm::StringRef(Sym.CanonicalDeclaration.FileURI).empty())
+ if (!llvm::StringRef(Sym.CanonicalDeclaration.fileURI()).empty())
for (const auto &ProximityURI :
- generateProximityURIs(Sym.CanonicalDeclaration.FileURI))
+ generateProximityURIs(Sym.CanonicalDeclaration.fileURI()))
ProximityDocs[ProximityURI].push_back(D);
if (Sym.Flags & Symbol::IndexedForCodeCompletion)
RestrictedCCDocs.push_back(D);
diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp b/clang-tools-extra/clangd/refactor/Rename.cpp
index c85e13dbdfe97f..3ca371ca833fdb 100644
--- a/clang-tools-extra/clangd/refactor/Rename.cpp
+++ b/clang-tools-extra/clangd/refactor/Rename.cpp
@@ -40,7 +40,7 @@ namespace clang {
namespace clangd {
namespace {
-std::optional<std::string> filePath(const SymbolLocation &Loc,
+std::optional<std::string> filePath(const SymbolNameLocation &Loc,
llvm::StringRef HintFilePath) {
if (!Loc)
return std::nullopt;
@@ -831,7 +831,7 @@ renameWithinFile(ParsedAST &AST, const NamedDecl &RenameDecl,
return FilteredChanges;
}
-Range toRange(const SymbolLocation &L) {
+Range toRange(const SymbolNameLocation &L) {
Range R;
R.start.line = L.Start.line();
R.start.character = L.Start.column();
diff --git a/clang-tools-extra/clangd/test/Inputs/symbols.test.yaml b/clang-tools-extra/clangd/test/Inputs/symbols.test.yaml
index 6d457ad8ad498c..936854e039f48a 100644
--- a/clang-tools-extra/clangd/test/Inputs/symbols.test.yaml
+++ b/clang-tools-extra/clangd/test/Inputs/symbols.test.yaml
@@ -3,15 +3,22 @@
ID: 057557CEBF6E6B2D
Name: 'vector'
Scope: 'std::'
-SymInfo:
+SymInfo:
Kind: Class
Lang: Cpp
-CanonicalDeclaration:
- FileURI: 'test:///vector.h'
- Start:
+CanonicalDeclaration:
+ NameLoc:
+ FileURI: 'test:///vector.h'
+ Start:
+ Line: 215
+ Column: 10
+ End:
+ Line: 215
+ Column: 16
+ Start:
Line: 215
Column: 10
- End:
+ End:
Line: 215
Column: 16
...
diff --git a/clang-tools-extra/clangd/test/index-serialization/Inputs/sample.idx b/clang-tools-extra/clangd/test/index-serialization/Inputs/sample.idx
index 6368e7145b1e4d628708f40d684bc8db1ef7f94d..1004f254f7adc4d7645f00bfc55765a128a853d9 100644
GIT binary patch
delta 250
zcmcb{{DHYX$kWa31tSB4bBbq0ZfZ#)3j+g#2oM*S6lJyn=|4bRF=ub at LEdHq9tLAB
z?uP$1zgHZQ$a^H_-6wmL?V_K5VEK#3OD@;y-QBQU|MQ%8Y2wp!XI)-&ac#~_Hkm)M
z@@m0Vn=bG$#0iA0W~qGp=HQBe4EBk8oy4wOmq>f0qbz&zV>lN}B}4YY<dRoChva$8
zT3v68@%3%x^xe62f6cWLrn2MFEX9?%N%JOd6y;@OVv}HJV`t+AF(#gt;$>lAXJThz
sXW;@dCccv5WoBSy;$UWH<^nM$b27^CvM{lTbFlEU2!j}twHVg`0JkAg2><{9
delta 263
zcmeyse2uw2$kWa393umRbBbq0ZfZ#)3j+g#2oM*S6lHb;X%3)V#hkspj(p7qJS?9@
z>=^bvzu~MpFHvawlA<>nW*y(YvVP^a?b$Nxu-}eEes#mP-LH;rHS<gqdp~Qt3p3xh
zb={vt<XSbE4y>A*5Ey=PLT3B5udXL~XME?nCamJ-Q`xufl-Z?+vh`}slPyI~mh`yo
zRhZ6S71$VgtIST~+A))**ZxIB9~Ng(iNC>6T$!6x2Xs_rwc^j8b3*k6m{^$@*xA_G
zxWUB4vr;PTEbJ^?KqX+{yyfVXx9!PG*_fDtK4E5O<^mIwr5R;dIav5vgeSW&t^oj%
C(^)?N
diff --git a/clang-tools-extra/clangd/test/type-hierarchy-ext.test b/clang-tools-extra/clangd/test/type-hierarchy-ext.test
index 8d1a5dc31da0f1..bbc5db932e1617 100644
--- a/clang-tools-extra/clangd/test/type-hierarchy-ext.test
+++ b/clang-tools-extra/clangd/test/type-hierarchy-ext.test
@@ -17,11 +17,11 @@
# CHECK-NEXT: "name": "Child3",
# CHECK-NEXT: "range": {
# CHECK-NEXT: "end": {
-# CHECK-NEXT: "character": 13,
+# CHECK-NEXT: "character": 26,
# CHECK-NEXT: "line": 3
# CHECK-NEXT: },
# CHECK-NEXT: "start": {
-# CHECK-NEXT: "character": 7,
+# CHECK-NEXT: "character": 0,
# CHECK-NEXT: "line": 3
# CHECK-NEXT: }
# CHECK-NEXT: },
@@ -159,11 +159,11 @@
# CHECK-NEXT: "name": "Child4",
# CHECK-NEXT: "range": {
# CHECK-NEXT: "end": {
-# CHECK-NEXT: "character": 13,
+# CHECK-NEXT: "character": 26,
# CHECK-NEXT: "line": 4
# CHECK-NEXT: },
# CHECK-NEXT: "start": {
-# CHECK-NEXT: "character": 7,
+# CHECK-NEXT: "character": 0,
# CHECK-NEXT: "line": 4
# CHECK-NEXT: }
# CHECK-NEXT: },
diff --git a/clang-tools-extra/clangd/test/type-hierarchy.test b/clang-tools-extra/clangd/test/type-hierarchy.test
index a5f13ab13d0b3f..a55382323188a8 100644
--- a/clang-tools-extra/clangd/test/type-hierarchy.test
+++ b/clang-tools-extra/clangd/test/type-hierarchy.test
@@ -67,11 +67,11 @@
# CHECK-NEXT: "name": "Child1",
# CHECK-NEXT: "range": {
# CHECK-NEXT: "end": {
-# CHECK-NEXT: "character": 13,
+# CHECK-NEXT: "character": 26,
# CHECK-NEXT: "line": 1
# CHECK-NEXT: },
# CHECK-NEXT: "start": {
-# CHECK-NEXT: "character": 7,
+# CHECK-NEXT: "character": 0,
# CHECK-NEXT: "line": 1
# CHECK-NEXT: }
# CHECK-NEXT: },
@@ -118,11 +118,11 @@
# CHECK-NEXT: "name": "Child3",
# CHECK-NEXT: "range": {
# CHECK-NEXT: "end": {
-# CHECK-NEXT: "character": 13,
+# CHECK-NEXT: "character": 26,
# CHECK-NEXT: "line": 3
# CHECK-NEXT: },
# CHECK-NEXT: "start": {
-# CHECK-NEXT: "character": 7,
+# CHECK-NEXT: "character": 0,
# CHECK-NEXT: "line": 3
# CHECK-NEXT: }
# CHECK-NEXT: },
diff --git a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
index ada14c99393186..be44a1b521fc3a 100644
--- a/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
+++ b/clang-tools-extra/clangd/unittests/BackgroundIndexTests.cpp
@@ -30,9 +30,9 @@ namespace clangd {
MATCHER_P(named, N, "") { return arg.Name == N; }
MATCHER_P(qName, N, "") { return (arg.Scope + arg.Name).str() == N; }
MATCHER(declared, "") {
- return !StringRef(arg.CanonicalDeclaration.FileURI).empty();
+ return !StringRef(arg.CanonicalDeclaration.fileURI()).empty();
}
-MATCHER(defined, "") { return !StringRef(arg.Definition.FileURI).empty(); }
+MATCHER(defined, "") { return !StringRef(arg.Definition.fileURI()).empty(); }
MATCHER_P(fileURI, F, "") { return StringRef(arg.Location.FileURI) == F; }
::testing::Matcher<const RefSlab &>
refsAre(std::vector<::testing::Matcher<Ref>> Matchers) {
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 3acacf496e77f9..0419812c37a2fd 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -872,7 +872,7 @@ TEST(CompletionTest, IncludeInsertionPreprocessorIntegrationTests) {
auto BarURI = URI::create(testPath("sub/bar.h")).toString();
Symbol Sym = cls("ns::X");
- Sym.CanonicalDeclaration.FileURI = BarURI.c_str();
+ Sym.CanonicalDeclaration.NameLocation.FileURI = BarURI.c_str();
Sym.IncludeHeaders.emplace_back(BarURI, 1, Symbol::Include);
// Shorten include path based on search directory and insert.
Annotations Test("int main() { ns::^ }");
@@ -902,8 +902,8 @@ TEST(CompletionTest, NoIncludeInsertionWhenDeclFoundInFile) {
Symbol SymY = cls("ns::Y");
std::string BarHeader = testPath("bar.h");
auto BarURI = URI::create(BarHeader).toString();
- SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
- SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
+ SymX.CanonicalDeclaration.NameLocation.FileURI = BarURI.c_str();
+ SymY.CanonicalDeclaration.NameLocation.FileURI = BarURI.c_str();
SymX.IncludeHeaders.emplace_back("<bar>", 1, Symbol::Include);
SymY.IncludeHeaders.emplace_back("<bar>", 1, Symbol::Include);
// Shorten include path based on search directory and insert.
@@ -1982,7 +1982,7 @@ TEST(CompletionTest, OverloadBundling) {
// Differences in header-to-insert suppress bundling.
std::string DeclFile = URI::create(testPath("foo")).toString();
- NoArgsGFunc.CanonicalDeclaration.FileURI = DeclFile.c_str();
+ NoArgsGFunc.CanonicalDeclaration.NameLocation.FileURI = DeclFile.c_str();
NoArgsGFunc.IncludeHeaders.emplace_back("<foo>", 1, Symbol::Include);
EXPECT_THAT(
completions(Context + "int y = GFunc^", {NoArgsGFunc}, Opts).Completions,
@@ -2014,8 +2014,8 @@ TEST(CompletionTest, OverloadBundlingSameFileDifferentURI) {
Symbol SymY = sym("ns::X", index::SymbolKind::Function, "@F@\\0#I#");
std::string BarHeader = testPath("bar.h");
auto BarURI = URI::create(BarHeader).toString();
- SymX.CanonicalDeclaration.FileURI = BarURI.c_str();
- SymY.CanonicalDeclaration.FileURI = BarURI.c_str();
+ SymX.CanonicalDeclaration.NameLocation.FileURI = BarURI.c_str();
+ SymY.CanonicalDeclaration.NameLocation.FileURI = BarURI.c_str();
// The include header is different, but really it's the same file.
SymX.IncludeHeaders.emplace_back("\"bar.h\"", 1, Symbol::Include);
SymY.IncludeHeaders.emplace_back(BarURI.c_str(), 1, Symbol::Include);
@@ -2840,7 +2840,7 @@ TEST(CompletionTest, EnableSpeculativeIndexRequest) {
TEST(CompletionTest, InsertTheMostPopularHeader) {
std::string DeclFile = URI::create(testPath("foo")).toString();
Symbol Sym = func("Func");
- Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
+ Sym.CanonicalDeclaration.NameLocation.FileURI = DeclFile.c_str();
Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2, Symbol::Include);
Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000, Symbol::Include);
@@ -2853,7 +2853,7 @@ TEST(CompletionTest, InsertTheMostPopularHeader) {
TEST(CompletionTest, InsertIncludeOrImport) {
std::string DeclFile = URI::create(testPath("foo")).toString();
Symbol Sym = func("Func");
- Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
+ Sym.CanonicalDeclaration.NameLocation.FileURI = DeclFile.c_str();
Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000,
Symbol::Include | Symbol::Import);
CodeCompleteOptions Opts;
@@ -2888,7 +2888,7 @@ TEST(CompletionTest, NoInsertIncludeIfOnePresent) {
std::string DeclFile = URI::create(testPath("foo")).toString();
Symbol Sym = func("Func");
- Sym.CanonicalDeclaration.FileURI = DeclFile.c_str();
+ Sym.CanonicalDeclaration.NameLocation.FileURI = DeclFile.c_str();
Sym.IncludeHeaders.emplace_back("\"foo.h\"", 2, Symbol::Include);
Sym.IncludeHeaders.emplace_back("\"bar.h\"", 1000, Symbol::Include);
diff --git a/clang-tools-extra/clangd/unittests/DexTests.cpp b/clang-tools-extra/clangd/unittests/DexTests.cpp
index ca8b81b5cb3c0a..489c5e65ee97be 100644
--- a/clang-tools-extra/clangd/unittests/DexTests.cpp
+++ b/clang-tools-extra/clangd/unittests/DexTests.cpp
@@ -683,9 +683,10 @@ TEST(DexTest, SymbolIndexOptionsFilter) {
TEST(DexTest, ProximityPathsBoosting) {
auto RootSymbol = symbol("root::abc");
- RootSymbol.CanonicalDeclaration.FileURI = "unittest:///file.h";
+ RootSymbol.CanonicalDeclaration.NameLocation.FileURI = "unittest:///file.h";
auto CloseSymbol = symbol("close::abc");
- CloseSymbol.CanonicalDeclaration.FileURI = "unittest:///a/b/c/d/e/f/file.h";
+ CloseSymbol.CanonicalDeclaration.NameLocation.FileURI =
+ "unittest:///a/b/c/d/e/f/file.h";
std::vector<Symbol> Symbols{CloseSymbol, RootSymbol};
Dex I(Symbols, RefSlab(), RelationSlab(), true);
diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
index 7a47d6ebebf3b2..e55cb6f07a79d2 100644
--- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
@@ -1250,8 +1250,8 @@ buildIndexWithSymbol(llvm::ArrayRef<SymbolWithHeader> Syms) {
for (const auto &S : Syms) {
Symbol Sym = cls(S.QName);
Sym.Flags |= Symbol::IndexedForCodeCompletion;
- Sym.CanonicalDeclaration.FileURI = S.DeclaringFile.c_str();
- Sym.Definition.FileURI = S.DeclaringFile.c_str();
+ Sym.CanonicalDeclaration.NameLocation.FileURI = S.DeclaringFile.c_str();
+ Sym.Definition.NameLocation.FileURI = S.DeclaringFile.c_str();
Sym.IncludeHeaders.emplace_back(S.IncludeHeader, 1, Symbol::Include);
Slab.insert(Sym);
}
@@ -1309,7 +1309,8 @@ TEST(IncludeFixerTest, IncompleteType) {
TEST(IncludeFixerTest, IncompleteEnum) {
Symbol Sym = enm("X");
Sym.Flags |= Symbol::IndexedForCodeCompletion;
- Sym.CanonicalDeclaration.FileURI = Sym.Definition.FileURI = "unittest:///x.h";
+ Sym.CanonicalDeclaration.NameLocation.FileURI =
+ Sym.Definition.NameLocation.FileURI = "unittest:///x.h";
Sym.IncludeHeaders.emplace_back("\"x.h\"", 1, Symbol::Include);
SymbolSlab::Builder Slab;
Slab.insert(Sym);
@@ -1351,8 +1352,8 @@ int main() {
auto TU = TestTU::withCode(Test.code());
Symbol Sym = cls("ns::X");
Sym.Flags |= Symbol::IndexedForCodeCompletion;
- Sym.CanonicalDeclaration.FileURI = "unittest:///x.h";
- Sym.Definition.FileURI = "unittest:///x.cc";
+ Sym.CanonicalDeclaration.NameLocation.FileURI = "unittest:///x.h";
+ Sym.Definition.NameLocation.FileURI = "unittest:///x.cc";
Sym.IncludeHeaders.emplace_back("\"x.h\"", 1, Symbol::Include);
SymbolSlab::Builder Slab;
@@ -1683,7 +1684,7 @@ TEST(IncludeFixerTest, CImplicitFunctionDecl) {
Symbol Sym = func("foo");
Sym.Flags |= Symbol::IndexedForCodeCompletion;
- Sym.CanonicalDeclaration.FileURI = "unittest:///foo.h";
+ Sym.CanonicalDeclaration.NameLocation.FileURI = "unittest:///foo.h";
Sym.IncludeHeaders.emplace_back("\"foo.h\"", 1, Symbol::Include);
SymbolSlab::Builder Slab;
diff --git a/clang-tools-extra/clangd/unittests/FileIndexTests.cpp b/clang-tools-extra/clangd/unittests/FileIndexTests.cpp
index a92142fbcd7c4a..1cb9d91717abb4 100644
--- a/clang-tools-extra/clangd/unittests/FileIndexTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FileIndexTests.cpp
@@ -51,10 +51,10 @@ MATCHER_P(refRange, Range, "") {
}
MATCHER_P(fileURI, F, "") { return llvm::StringRef(arg.Location.FileURI) == F; }
MATCHER_P(declURI, U, "") {
- return llvm::StringRef(arg.CanonicalDeclaration.FileURI) == U;
+ return llvm::StringRef(arg.CanonicalDeclaration.fileURI()) == U;
}
MATCHER_P(defURI, U, "") {
- return llvm::StringRef(arg.Definition.FileURI) == U;
+ return llvm::StringRef(arg.Definition.fileURI()) == U;
}
MATCHER_P(qName, N, "") { return (arg.Scope + arg.Name).str() == N; }
MATCHER_P(numReferences, N, "") { return arg.References == N; }
@@ -133,9 +133,9 @@ TEST(FileSymbolsTest, MergeOverlap) {
return std::make_unique<SymbolSlab>(std::move(S).build());
};
auto X1 = symbol("x");
- X1.CanonicalDeclaration.FileURI = "file:///x1";
+ X1.CanonicalDeclaration.NameLocation.FileURI = "file:///x1";
auto X2 = symbol("x");
- X2.Definition.FileURI = "file:///x2";
+ X2.Definition.NameLocation.FileURI = "file:///x2";
FS.update("f1", OneSymboSlab(X1), nullptr, nullptr, false);
FS.update("f2", OneSymboSlab(X2), nullptr, nullptr, false);
@@ -610,11 +610,11 @@ TEST(FileShardedIndexTest, Sharding) {
auto BSourceUri = URI::create(testPath("b.cc")).toString();
auto Sym1 = symbol("1");
- Sym1.CanonicalDeclaration.FileURI = AHeaderUri.c_str();
+ Sym1.CanonicalDeclaration.NameLocation.FileURI = AHeaderUri.c_str();
auto Sym2 = symbol("2");
- Sym2.CanonicalDeclaration.FileURI = BHeaderUri.c_str();
- Sym2.Definition.FileURI = BSourceUri.c_str();
+ Sym2.CanonicalDeclaration.NameLocation.FileURI = BHeaderUri.c_str();
+ Sym2.Definition.NameLocation.FileURI = BSourceUri.c_str();
auto Sym3 = symbol("3"); // not stored
diff --git a/clang-tools-extra/clangd/unittests/IndexTests.cpp b/clang-tools-extra/clangd/unittests/IndexTests.cpp
index a66680d39c87d2..f67c996ab1b98b 100644
--- a/clang-tools-extra/clangd/unittests/IndexTests.cpp
+++ b/clang-tools-extra/clangd/unittests/IndexTests.cpp
@@ -42,7 +42,7 @@ MATCHER_P(refRange, Range, "") {
MATCHER_P(fileURI, F, "") { return StringRef(arg.Location.FileURI) == F; }
TEST(SymbolLocation, Position) {
- using Position = SymbolLocation::Position;
+ using Position = SymbolPosition;
Position Pos;
Pos.setLine(1);
@@ -385,8 +385,8 @@ TEST(MergeTest, Merge) {
Symbol L, R;
L.ID = R.ID = SymbolID("hello");
L.Name = R.Name = "Foo"; // same in both
- L.CanonicalDeclaration.FileURI = "file:///left.h"; // differs
- R.CanonicalDeclaration.FileURI = "file:///right.h";
+ L.CanonicalDeclaration.NameLocation.FileURI = "file:///left.h"; // differs
+ R.CanonicalDeclaration.NameLocation.FileURI = "file:///right.h";
L.References = 1;
R.References = 2;
L.Signature = "()"; // present in left only
@@ -398,7 +398,7 @@ TEST(MergeTest, Merge) {
Symbol M = mergeSymbol(L, R);
EXPECT_EQ(M.Name, "Foo");
- EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:///left.h");
+ EXPECT_EQ(StringRef(M.CanonicalDeclaration.fileURI()), "file:///left.h");
EXPECT_EQ(M.References, 3u);
EXPECT_EQ(M.Signature, "()");
EXPECT_EQ(M.CompletionSnippetSuffix, "{$1:0}");
@@ -412,20 +412,21 @@ TEST(MergeTest, PreferSymbolWithDefn) {
Symbol L, R;
L.ID = R.ID = SymbolID("hello");
- L.CanonicalDeclaration.FileURI = "file:/left.h";
- R.CanonicalDeclaration.FileURI = "file:/right.h";
+ L.CanonicalDeclaration.NameLocation.FileURI = "file:/left.h";
+ R.CanonicalDeclaration.NameLocation.FileURI = "file:/right.h";
L.Name = "left";
R.Name = "right";
Symbol M = mergeSymbol(L, R);
- EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/left.h");
- EXPECT_EQ(StringRef(M.Definition.FileURI), "");
+ EXPECT_EQ(StringRef(M.CanonicalDeclaration.fileURI()), "file:/left.h");
+ EXPECT_EQ(StringRef(M.Definition.fileURI()), "");
EXPECT_EQ(M.Name, "left");
- R.Definition.FileURI = "file:/right.cpp"; // Now right will be favored.
+ R.Definition.NameLocation.FileURI =
+ "file:/right.cpp"; // Now right will be favored.
M = mergeSymbol(L, R);
- EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/right.h");
- EXPECT_EQ(StringRef(M.Definition.FileURI), "file:/right.cpp");
+ EXPECT_EQ(StringRef(M.CanonicalDeclaration.fileURI()), "file:/right.h");
+ EXPECT_EQ(StringRef(M.Definition.fileURI()), "file:/right.cpp");
EXPECT_EQ(M.Name, "right");
}
@@ -433,16 +434,16 @@ TEST(MergeTest, PreferSymbolLocationInCodegenFile) {
Symbol L, R;
L.ID = R.ID = SymbolID("hello");
- L.CanonicalDeclaration.FileURI = "file:/x.proto.h";
- R.CanonicalDeclaration.FileURI = "file:/x.proto";
+ L.CanonicalDeclaration.NameLocation.FileURI = "file:/x.proto.h";
+ R.CanonicalDeclaration.NameLocation.FileURI = "file:/x.proto";
Symbol M = mergeSymbol(L, R);
- EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/x.proto");
+ EXPECT_EQ(StringRef(M.CanonicalDeclaration.fileURI()), "file:/x.proto");
// Prefer L if both have codegen suffix.
- L.CanonicalDeclaration.FileURI = "file:/y.proto";
+ L.CanonicalDeclaration.NameLocation.FileURI = "file:/y.proto";
M = mergeSymbol(L, R);
- EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/y.proto");
+ EXPECT_EQ(StringRef(M.CanonicalDeclaration.fileURI()), "file:/y.proto");
}
TEST(MergeIndexTest, Refs) {
@@ -545,7 +546,7 @@ TEST(MergeIndexTest, NonDocumentation) {
using index::SymbolKind;
Symbol L, R;
L.ID = R.ID = SymbolID("x");
- L.Definition.FileURI = "file:/x.h";
+ L.Definition.NameLocation.FileURI = "file:/x.h";
R.Documentation = "Forward declarations because x.h is too big to include";
for (auto ClassLikeKind :
{SymbolKind::Class, SymbolKind::Struct, SymbolKind::Union}) {
@@ -578,20 +579,20 @@ TEST(MergeTest, MergeIncludesOnDifferentDefinitions) {
IncludeHeaderWithRef("new", 1u)));
// Only merge references of the same includes but do not merge new #includes.
- L.Definition.FileURI = "file:/left.h";
+ L.Definition.NameLocation.FileURI = "file:/left.h";
M = mergeSymbol(L, R);
EXPECT_THAT(M.IncludeHeaders,
UnorderedElementsAre(IncludeHeaderWithRef("common", 2u)));
// Definitions are the same.
- R.Definition.FileURI = "file:/right.h";
+ R.Definition.NameLocation.FileURI = "file:/right.h";
M = mergeSymbol(L, R);
EXPECT_THAT(M.IncludeHeaders,
UnorderedElementsAre(IncludeHeaderWithRef("common", 2u),
IncludeHeaderWithRef("new", 1u)));
// Definitions are different.
- R.Definition.FileURI = "file:/right.h";
+ R.Definition.NameLocation.FileURI = "file:/right.h";
M = mergeSymbol(L, R);
EXPECT_THAT(M.IncludeHeaders,
UnorderedElementsAre(IncludeHeaderWithRef("common", 2u),
@@ -600,7 +601,7 @@ TEST(MergeTest, MergeIncludesOnDifferentDefinitions) {
TEST(MergeIndexTest, IncludeHeadersMerged) {
auto S = symbol("Z");
- S.Definition.FileURI = "unittest:///foo.cc";
+ S.Definition.NameLocation.FileURI = "unittest:///foo.cc";
SymbolSlab::Builder DynB;
S.IncludeHeaders.clear();
@@ -609,7 +610,7 @@ TEST(MergeIndexTest, IncludeHeadersMerged) {
RefSlab DynRefs;
auto DynSize = DynSymbols.bytes() + DynRefs.bytes();
auto DynData = std::make_pair(std::move(DynSymbols), std::move(DynRefs));
- llvm::StringSet<> DynFiles = {S.Definition.FileURI};
+ llvm::StringSet<> DynFiles = {S.Definition.fileURI()};
MemIndex DynIndex(std::move(DynData.first), std::move(DynData.second),
RelationSlab(), std::move(DynFiles), IndexContents::Symbols,
std::move(DynData), DynSize);
diff --git a/clang-tools-extra/clangd/unittests/SerializationTests.cpp b/clang-tools-extra/clangd/unittests/SerializationTests.cpp
index 2a7a6c36d3d17f..4775274b5da14b 100644
--- a/clang-tools-extra/clangd/unittests/SerializationTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SerializationTests.cpp
@@ -41,7 +41,14 @@ Scope: 'clang::'
Kind: Function
Lang: Cpp
CanonicalDeclaration:
- FileURI: file:///path/foo.h
+ NameLoc:
+ FileURI: file:///path/foo.h
+ Start:
+ Line: 1
+ Column: 0
+ End:
+ Line: 1
+ Column: 1
Start:
Line: 1
Column: 0
@@ -74,7 +81,14 @@ Scope: 'clang::'
Kind: Function
Lang: Cpp
CanonicalDeclaration:
- FileURI: file:///path/bar.h
+ NameLoc:
+ FileURI: file:///path/bar.h
+ Start:
+ Line: 1
+ Column: 0
+ End:
+ Line: 1
+ Column: 1
Start:
Line: 1
Column: 0
@@ -155,7 +169,8 @@ TEST(SerializationTest, YAMLConversions) {
EXPECT_EQ(Sym1.Signature, "");
EXPECT_EQ(Sym1.Documentation, "Foo doc");
EXPECT_EQ(Sym1.ReturnType, "int");
- EXPECT_EQ(StringRef(Sym1.CanonicalDeclaration.FileURI), "file:///path/foo.h");
+ EXPECT_EQ(StringRef(Sym1.CanonicalDeclaration.fileURI()),
+ "file:///path/foo.h");
EXPECT_EQ(Sym1.Origin, SymbolOrigin::Static);
EXPECT_EQ(static_cast<uint8_t>(Sym1.Flags), 129);
EXPECT_TRUE(Sym1.Flags & Symbol::IndexedForCodeCompletion);
@@ -172,7 +187,7 @@ TEST(SerializationTest, YAMLConversions) {
EXPECT_THAT(Sym2, qName("clang::Foo2"));
EXPECT_EQ(Sym2.Signature, "-sig");
EXPECT_EQ(Sym2.ReturnType, "");
- EXPECT_EQ(llvm::StringRef(Sym2.CanonicalDeclaration.FileURI),
+ EXPECT_EQ(llvm::StringRef(Sym2.CanonicalDeclaration.fileURI()),
"file:///path/bar.h");
EXPECT_FALSE(Sym2.Flags & Symbol::IndexedForCodeCompletion);
EXPECT_TRUE(Sym2.Flags & Symbol::Deprecated);
diff --git a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
index e8088cb37fa51c..6d16d14dd9917d 100644
--- a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp
@@ -64,9 +64,9 @@ MATCHER_P(templateArgs, TemplArgs, "") {
}
MATCHER_P(hasKind, Kind, "") { return arg.SymInfo.Kind == Kind; }
MATCHER_P(declURI, P, "") {
- return StringRef(arg.CanonicalDeclaration.FileURI) == P;
+ return StringRef(arg.CanonicalDeclaration.fileURI()) == P;
}
-MATCHER_P(defURI, P, "") { return StringRef(arg.Definition.FileURI) == P; }
+MATCHER_P(defURI, P, "") { return StringRef(arg.Definition.fileURI()) == P; }
MATCHER(includeHeader, "") { return !arg.IncludeHeaders.empty(); }
MATCHER_P(includeHeader, P, "") {
return (arg.IncludeHeaders.size() == 1) &&
@@ -75,16 +75,18 @@ MATCHER_P(includeHeader, P, "") {
MATCHER_P2(IncludeHeaderWithRef, includeHeader, References, "") {
return (arg.IncludeHeader == includeHeader) && (arg.References == References);
}
-bool rangesMatch(const SymbolLocation &Loc, const Range &R) {
+bool rangesMatch(const SymbolNameLocation &Loc, const Range &R) {
return std::make_tuple(Loc.Start.line(), Loc.Start.column(), Loc.End.line(),
Loc.End.column()) ==
std::make_tuple(R.start.line, R.start.character, R.end.line,
R.end.character);
}
MATCHER_P(declRange, Pos, "") {
- return rangesMatch(arg.CanonicalDeclaration, Pos);
+ return rangesMatch(arg.CanonicalDeclaration.NameLocation, Pos);
+}
+MATCHER_P(defRange, Pos, "") {
+ return rangesMatch(arg.Definition.NameLocation, Pos);
}
-MATCHER_P(defRange, Pos, "") { return rangesMatch(arg.Definition, Pos); }
MATCHER_P(refCount, R, "") { return int(arg.References) == R; }
MATCHER_P(forCodeCompletion, IsIndexedForCodeCompletion, "") {
return static_cast<bool>(arg.Flags & Symbol::IndexedForCodeCompletion) ==
More information about the cfe-commits
mailing list