Skip to content

Commit b279e4b

Browse files
committed
[clang] Skip unqualified members in explicit-member functions
1 parent d42a1d4 commit b279e4b

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4473,6 +4473,45 @@ TEST(CompletionTest, SkipExplicitObjectParameter) {
44734473
snippetSuffix(""))));
44744474
}
44754475
}
4476+
4477+
TEST(CompletionTest, MemberAccessInExplicitObjMemfn) {
4478+
Annotations Code(R"cpp(
4479+
struct A {
4480+
int member {};
4481+
4482+
void foo(this A& self) {
4483+
// Should not offer `member` here, since it needs to be
4484+
// referenced as `self.member`.
4485+
mem$c1^;
4486+
self.mem$c2^;
4487+
}
4488+
};
4489+
)cpp");
4490+
4491+
auto TU = TestTU::withCode(Code.code());
4492+
TU.ExtraArgs = {"-std=c++23"};
4493+
4494+
auto Preamble = TU.preamble();
4495+
ASSERT_TRUE(Preamble);
4496+
4497+
CodeCompleteOptions Opts{};
4498+
4499+
MockFS FS;
4500+
auto Inputs = TU.inputs(FS);
4501+
4502+
{
4503+
auto Result = codeComplete(testPath(TU.Filename), Code.point("c1"),
4504+
Preamble.get(), Inputs, Opts);
4505+
4506+
EXPECT_THAT(Result.Completions, ElementsAre());
4507+
}
4508+
{
4509+
auto Result = codeComplete(testPath(TU.Filename), Code.point("c2"),
4510+
Preamble.get(), Inputs, Opts);
4511+
4512+
EXPECT_THAT(Result.Completions, ElementsAre(named("member")));
4513+
}
4514+
}
44764515
} // namespace
44774516
} // namespace clangd
44784517
} // namespace clang

clang/lib/Sema/SemaCodeComplete.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1428,6 +1428,16 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
14281428

14291429
AdjustResultPriorityForDecl(R);
14301430

1431+
if (isa<FieldDecl>(R.Declaration)) {
1432+
// If result is a member in the context of an explicit-object member
1433+
// function, drop it because it must be accessed through the object
1434+
// parameter
1435+
if (auto *MethodDecl = dyn_cast<CXXMethodDecl>(CurContext);
1436+
MethodDecl && MethodDecl->isExplicitObjectMemberFunction()) {
1437+
return;
1438+
}
1439+
}
1440+
14311441
if (HasObjectTypeQualifiers)
14321442
if (const auto *Method = dyn_cast<CXXMethodDecl>(R.Declaration))
14331443
if (Method->isInstance()) {

0 commit comments

Comments
 (0)