diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp --- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp +++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp @@ -2184,6 +2184,42 @@ EXPECT_TRUE(R.additionalTextEdits.empty()); } +TEST(CompletionTest, FixItForMembersUsing) { + const Annotations Code(R"cpp( + struct Bar { + void method(); + int field; + }; + struct Baz : Bar { + using Bar::method; + using Bar::field; + }; + void foo(Baz* ptr) { + ptr.m^ethod(); + ptr.f^ield; + } + )cpp"); + + TestTU TU; + TU.Code = Code.code().str(); + auto CheckCompletion = [&TU](const Position &Pos, const std::string &Name) { + clangd::CodeCompleteOptions Opts; + Opts.IncludeFixIts = true; + + const auto Completions = completions(TU, Pos, {}, Opts).Completions; + ASSERT_EQ(Completions.size(), 1u); + EXPECT_EQ(Completions[0].Name, Name); + + const auto R = Completions[0].render(Opts); + ASSERT_TRUE(R.textEdit); + EXPECT_EQ(R.textEdit->newText, "->" + Name); + }; + + const auto Points = Code.points(); + CheckCompletion(Points[0], "method"); + CheckCompletion(Points[1], "field"); +} + TEST(CompletionTest, RenderWithFixItNonMerged) { TextEdit FixIt; FixIt.range.end.character = 4; diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp --- a/clang/lib/Sema/SemaCodeComplete.cpp +++ b/clang/lib/Sema/SemaCodeComplete.cpp @@ -1275,6 +1275,7 @@ (R.Availability == CXAvailability_Available || R.Availability == CXAvailability_Deprecated)); Result.ShadowDecl = Using; + Result.FixIts = R.FixIts; AddResult(Result, CurContext, Hiding); return; } diff --git a/clang/test/CodeCompletion/member-access.cpp b/clang/test/CodeCompletion/member-access.cpp --- a/clang/test/CodeCompletion/member-access.cpp +++ b/clang/test/CodeCompletion/member-access.cpp @@ -311,3 +311,25 @@ // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:310:19 %s -o - | FileCheck -check-prefix=CHECK-MEMBERS-FROM-BASE-DEPENDENT %s // CHECK-MEMBERS-FROM-BASE-DEPENDENT: [#Base4#]base4 } + +namespace members_using_fixits { + struct Bar { + void method(); + int field; + }; + struct Baz: Bar { + using Bar::method; + using Bar::field; + }; + void testMethod(Baz* ptr) { + ptr.m + } + // RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:325:10 %s -o - | FileCheck -check-prefix=CHECK-METHOD-DECLARED-VIA-USING %s + // CHECK-METHOD-DECLARED-VIA-USING: [#void#]method() (requires fix-it: {325:8-325:9} to "->") + + void testField(Baz* ptr) { + ptr.f + } + // RUN: %clang_cc1 -fsyntax-only -code-completion-with-fixits -code-completion-at=%s:331:10 %s -o - | FileCheck -check-prefix=CHECK-FIELD-DECLARED-VIA-USING %s + // CHECK-FIELD-DECLARED-VIA-USING: [#int#]field (requires fix-it: {331:8-331:9} to "->") +}