diff --git a/clang-tools-extra/clangd/XRefs.h b/clang-tools-extra/clangd/XRefs.h --- a/clang-tools-extra/clangd/XRefs.h +++ b/clang-tools-extra/clangd/XRefs.h @@ -16,6 +16,7 @@ #include "Protocol.h" #include "SourceCode.h" #include "index/Index.h" +#include "index/SymbolID.h" #include "index/SymbolLocation.h" #include "support/Path.h" #include "clang/AST/ASTTypeTraits.h" @@ -47,6 +48,8 @@ Location PreferredDeclaration; // Where the symbol is defined, if known. May equal PreferredDeclaration. llvm::Optional Definition; + // SymbolID of the symbol. Not present for file referents. + llvm::Optional ID; }; llvm::raw_ostream &operator<<(llvm::raw_ostream &, const LocatedSymbol &); /// Get definition of symbol at a specified \p Pos. diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp --- a/clang-tools-extra/clangd/XRefs.cpp +++ b/clang-tools-extra/clangd/XRefs.cpp @@ -257,6 +257,7 @@ Macro.Name = std::string(M->Name); Macro.PreferredDeclaration = *Loc; Macro.Definition = Loc; + Macro.ID = getSymbolID(M->Name, M->Info, AST.getSourceManager()); return Macro; } } @@ -361,6 +362,7 @@ Result.emplace_back(); Result.back().Name = printName(AST.getASTContext(), *D); Result.back().PreferredDeclaration = *Loc; + Result.back().ID = getSymbolID(D); if (const NamedDecl *Def = getDefinition(D)) Result.back().Definition = makeLocation( AST.getASTContext(), nameLocation(*Def, SM), MainFilePath); @@ -516,6 +518,7 @@ Results.emplace_back(); Results.back().Name = printName(ASTContext, *D); Results.back().PreferredDeclaration = *Loc; + Results.back().ID = getSymbolID(D); if (const NamedDecl *Def = getDefinition(D)) Results.back().Definition = makeLocation(ASTContext, nameLocation(*Def, SM), *MainFilePath); @@ -605,6 +608,7 @@ LocatedSymbol Located; Located.PreferredDeclaration = *MaybeDeclLoc; Located.Name = (Sym.Name + Sym.TemplateSpecializationArgs).str(); + Located.ID = Sym.ID; if (Sym.Definition) { auto MaybeDefLoc = indexToLSPLocation(Sym.Definition, MainFilePath); if (!MaybeDefLoc) { diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -306,6 +306,8 @@ MATCHER_P(RangeIs, R, "") { return arg.Loc.range == R; } MATCHER_P(AttrsAre, A, "") { return arg.Attributes == A; } +MATCHER(HasID, "") { return arg.ID.hasValue(); } +MATCHER_P(HasID, ID, "") { return arg.ID.getValue() == ID; } TEST(LocateSymbol, WithIndex) { Annotations SymbolHeader(R"cpp( @@ -919,6 +921,7 @@ } else { ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test; EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test; + EXPECT_THAT(Results[0], HasID()) << Test; llvm::Optional GotDef; if (Results[0].Definition) GotDef = Results[0].Definition->range; @@ -926,6 +929,24 @@ } } } +TEST(LocateSymbol, ValidSymbolID) { + auto T = Annotations(R"cpp( + #define MACRO(x, y) ((x) + (y)) + int add(int x, int y) { return $MACRO^MACRO(x, y); } + int sum = $add^add(1, 2); + )cpp"); + + TestTU TU = TestTU::withCode(T.code()); + auto AST = TU.build(); + auto Index = TU.index(); + EXPECT_THAT(locateSymbolAt(AST, T.point("add"), Index.get()), + ElementsAre(AllOf(Sym("add"), + HasID(getSymbolID(&findDecl(AST, "add")))))); + EXPECT_THAT( + locateSymbolAt(AST, T.point("MACRO"), Index.get()), + ElementsAre(AllOf(Sym("MACRO"), + HasID(findSymbol(TU.headerSymbols(), "MACRO").ID)))); +} TEST(LocateSymbol, AllMulti) { // Ranges in tests: @@ -1072,8 +1093,10 @@ auto TU = TestTU::withCode(T.code()); auto AST = TU.build(); auto Index = TU.index(); - EXPECT_THAT(locateSymbolAt(AST, T.point(), Index.get()), - ElementsAre(Sym("MyClass", T.range(), T.range()))); + EXPECT_THAT( + locateSymbolAt(AST, T.point(), Index.get()), + ElementsAre(AllOf(Sym("MyClass", T.range(), T.range()), + HasID(getSymbolID(&findDecl(AST, "MyClass")))))); } TEST(LocateSymbol, Textual) {