Index: clangd/global-symbol-builder/GlobalSymbolBuilderMain.cpp =================================================================== --- clangd/global-symbol-builder/GlobalSymbolBuilderMain.cpp +++ clangd/global-symbol-builder/GlobalSymbolBuilderMain.cpp @@ -83,6 +83,7 @@ IndexOpts.IndexFunctionLocals = false; auto CollectorOpts = SymbolCollector::Options(); CollectorOpts.FallbackDir = AssumedHeaderDir; + CollectorOpts.Revision = Ctx->getRevision(); return new WrappedIndexAction( std::make_shared(std::move(CollectorOpts)), IndexOpts, Ctx); Index: clangd/index/Index.h =================================================================== --- clangd/index/Index.h +++ clangd/index/Index.h @@ -126,6 +126,10 @@ // (not a definition), which is usually declared in ".h" file. SymbolLocation CanonicalDeclaration; + // The source control symbol's revision number from which the symbol is + // indexed. + llvm::StringRef Revision; + /// A brief description of the symbol that can be displayed in the completion /// candidate list. For example, "Foo(X x, Y y) const" is a labal for a /// function. Index: clangd/index/Index.cpp =================================================================== --- clangd/index/Index.cpp +++ clangd/index/Index.cpp @@ -55,6 +55,7 @@ Intern(S.Name); Intern(S.Scope); Intern(S.CanonicalDeclaration.FilePath); + Intern(S.Revision); Intern(S.CompletionLabel); Intern(S.CompletionFilterText); Index: clangd/index/SymbolCollector.h =================================================================== --- clangd/index/SymbolCollector.h +++ clangd/index/SymbolCollector.h @@ -34,6 +34,9 @@ // VFS that does not have absolute path), combine the fallback directory // with symbols' paths to get absolute paths. This must be an absolute path. std::string FallbackDir; + // The source control symbol's revision number on which SymbolCollector + // runs. + std::string Revision; }; SymbolCollector(Options Opts); Index: clangd/index/SymbolCollector.cpp =================================================================== --- clangd/index/SymbolCollector.cpp +++ clangd/index/SymbolCollector.cpp @@ -204,6 +204,8 @@ std::string FilePath; S.CanonicalDeclaration = GetSymbolLocation(ND, SM, Opts.FallbackDir, FilePath); + S.Revision = Opts.Revision; + // Add completion info. assert(ASTCtx && PP.get() && "ASTContext and Preprocessor must be set."); CodeCompletionResult SymbolCompletion(ND, 0); Index: clangd/index/SymbolYAML.cpp =================================================================== --- clangd/index/SymbolYAML.cpp +++ clangd/index/SymbolYAML.cpp @@ -97,6 +97,7 @@ IO.mapRequired("Name", Sym.Name); IO.mapRequired("Scope", Sym.Scope); IO.mapRequired("SymInfo", Sym.SymInfo); + IO.mapRequired("Revision", Sym.Revision); IO.mapRequired("CanonicalDeclaration", Sym.CanonicalDeclaration); IO.mapRequired("CompletionLabel", Sym.CompletionLabel); IO.mapRequired("CompletionFilterText", Sym.CompletionFilterText); Index: unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- unittests/clangd/SymbolCollectorTests.cpp +++ unittests/clangd/SymbolCollectorTests.cpp @@ -47,6 +47,7 @@ } MATCHER_P(QName, Name, "") { return (arg.Scope + arg.Name).str() == Name; } MATCHER_P(CPath, P, "") { return arg.CanonicalDeclaration.FilePath == P; } +MATCHER_P(Revision, R, "") { return arg.Revision == R; } MATCHER_P(LocationOffsets, Offsets, "") { // Offset range in SymbolLocation is [start, end] while in Clangd is [start, // end). @@ -167,9 +168,11 @@ TEST_F(SymbolCollectorTest, SymbolRelativeNoFallback) { CollectorOpts.IndexMainFiles = false; + CollectorOpts.Revision = "1234"; runSymbolCollector("class Foo {};", /*Main=*/""); EXPECT_THAT(Symbols, - UnorderedElementsAre(AllOf(QName("Foo"), CPath("symbols.h")))); + UnorderedElementsAre(AllOf(QName("Foo"), CPath("symbols.h"), + Revision(CollectorOpts.Revision)))); } TEST_F(SymbolCollectorTest, SymbolRelativeWithFallback) { @@ -434,6 +437,7 @@ StartOffset: 0 EndOffset: 1 FilePath: /path/foo.h +Revision: 1234 CompletionLabel: 'Foo1-label' CompletionFilterText: 'filter' CompletionPlainInsertText: 'plain' @@ -454,6 +458,7 @@ StartOffset: 10 EndOffset: 12 FilePath: /path/foo.h +Revision: 1234 CompletionLabel: 'Foo2-label' CompletionFilterText: 'filter' CompletionPlainInsertText: 'plain' @@ -462,11 +467,13 @@ )"; auto Symbols1 = SymbolFromYAML(YAML1); - EXPECT_THAT(Symbols1, UnorderedElementsAre( - AllOf(QName("clang::Foo1"), Labeled("Foo1-label"), - Doc("Foo doc"), Detail("int")))); + EXPECT_THAT(Symbols1, + UnorderedElementsAre(AllOf(QName("clang::Foo1"), Revision("1234"), + Labeled("Foo1-label"), Doc("Foo doc"), + Detail("int")))); auto Symbols2 = SymbolFromYAML(YAML2); EXPECT_THAT(Symbols2, UnorderedElementsAre(AllOf(QName("clang::Foo2"), + Revision("1234"), Labeled("Foo2-label"), Not(HasDetail()))));