Index: clangd/CodeComplete.cpp =================================================================== --- clangd/CodeComplete.cpp +++ clangd/CodeComplete.cpp @@ -728,9 +728,9 @@ // Retain the results we might want. for (unsigned I = 0; I < NumResults; ++I) { auto &Result = InResults[I]; - // Drop hidden items which cannot be found by lookup after completion. - // Exception: some items can be named by using a qualifier. - if (Result.Hidden && (!Result.Qualifier || Result.QualifierIsInformative)) + // Class members that are shadowed by subclasses are usually noise. + if (Result.Hidden && Result.Declaration && + Result.Declaration->isCXXClassMember()) continue; if (!Opts.IncludeIneligibleResults && (Result.Availability == CXAvailability_NotAvailable || Index: unittests/clangd/CodeCompleteTests.cpp =================================================================== --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -371,6 +371,8 @@ TEST(CompletionTest, Qualifiers) { auto Results = completions(R"cpp( + namespace x { + int foo(); class Foo { public: int foo() const; int bar() const; @@ -379,12 +381,16 @@ int foo() const; }; void test() { Bar().^ } + } )cpp"); EXPECT_THAT(Results.Completions, - HasSubsequence(AllOf(Qualifier(""), Named("bar")), - AllOf(Qualifier("Foo::"), Named("foo")))); + Contains(AllOf(Qualifier(""), Named("bar")))); + // Hidden members are not shown. + EXPECT_THAT(Results.Completions, + Not(Contains(AllOf(Qualifier("Foo::"), Named("foo"))))); + // Private members are not shown. EXPECT_THAT(Results.Completions, - Not(Contains(AllOf(Qualifier(""), Named("foo"))))); // private + Not(Contains(AllOf(Qualifier(""), Named("foo"))))); } TEST(CompletionTest, InjectedTypename) {