Index: unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- unittests/clangd/SymbolCollectorTests.cpp +++ unittests/clangd/SymbolCollectorTests.cpp @@ -7,8 +7,13 @@ //===----------------------------------------------------------------------===// #include "Annotations.h" +#include "ClangdServer.h" +#include "CodeComplete.h" +#include "SyncAPI.h" #include "TestFS.h" #include "TestTU.h" +#include "index/Index.h" +#include "index/MemIndex.h" #include "index/SymbolCollector.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemOptions.h" @@ -50,6 +55,7 @@ MATCHER_P(Snippet, S, "") { return (arg.Name + arg.CompletionSnippetSuffix).str() == S; } +MATCHER_P(CompletionQName, Name, "") { return (arg.Scope + arg.Name) == Name; } MATCHER_P(QName, Name, "") { return (arg.Scope + arg.Name).str() == Name; } MATCHER_P(DeclURI, P, "") { return StringRef(arg.CanonicalDeclaration.FileURI) == P; @@ -325,9 +331,6 @@ // Namespace alias namespace baz = bar; - // FIXME: using declaration is not supported as the IndexAction will ignore - // implicit declarations (the implicit using shadow declaration) by default, - // and there is no way to customize this behavior at the moment. using bar::v2; } // namespace foo )"; @@ -354,6 +357,7 @@ AllOf(QName("foo::int32_t"), ForCodeCompletion(true)), AllOf(QName("foo::v1"), ForCodeCompletion(true)), AllOf(QName("foo::bar::v2"), ForCodeCompletion(true)), + AllOf(QName("foo::v2"), ForCodeCompletion(true)), AllOf(QName("foo::baz"), ForCodeCompletion(true))})); } @@ -1118,6 +1122,48 @@ AllOf(QName("Public"), Not(ImplementationDetail())))); } +TEST_F(SymbolCollectorTest, UsingDecl) { + auto completions = [](const Annotations &Test, SymbolSlab SS) { + class IgnoreDiagnostics : public DiagnosticsConsumer { + void onDiagnosticsReady(PathRef File, + std::vector Diagnostics) override {} + }; + + MockFSProvider FS; + MockCompilationDatabase CDB; + IgnoreDiagnostics DiagConsumer; + ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + std::unique_ptr OverrideIndex = + MemIndex::build(std::move(SS), {}); + clangd::CodeCompleteOptions Opts; + Opts.Index = OverrideIndex.get(); + + auto File = testPath("foo.cpp"); + runAddDocument(Server, File, Test.code()); + auto CompletionList = + llvm::cantFail(runCodeComplete(Server, File, Test.point(), Opts)); + return CompletionList; + }; + + const Annotations Header(R"( + void foo(); + namespace std { + using ::foo; + } + void bar() { + (void)std::^foo; + })"); + runSymbolCollector(Header.code(), /**/ ""); + EXPECT_THAT(Symbols, Contains(QName("std::foo"))); + + const auto Results = completions(Header, std::move(Symbols)); + EXPECT_THAT( + Results.Completions, + Contains(AllOf( + ReturnType(/*Currently using decls does not export target info*/ ""), + CompletionQName("std::foo")))); +} + } // namespace } // namespace clangd } // namespace clang Index: unittests/clangd/SymbolInfoTests.cpp =================================================================== --- unittests/clangd/SymbolInfoTests.cpp +++ unittests/clangd/SymbolInfoTests.cpp @@ -167,7 +167,8 @@ )cpp", {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#"), CreateExpectedSymbolDetails("foo", "", "c:@F@foo#b#"), - CreateExpectedSymbolDetails("foo", "", "c:@F@foo#I#")}}, + CreateExpectedSymbolDetails("foo", "", "c:@F@foo#I#"), + CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@UD@foo")}}, { R"cpp( // Multiple symbols returned - implicit conversion struct foo {};