Index: unittests/clangd/CodeCompleteTests.cpp =================================================================== --- unittests/clangd/CodeCompleteTests.cpp +++ unittests/clangd/CodeCompleteTests.cpp @@ -2204,6 +2204,115 @@ {cls("naber"), cls("nx::naber")}, Opts); EXPECT_THAT(Results.Completions, UnorderedElementsAre()); } + +TEST(CompletionTest, NoCompletionForSpecialMembers) { + clangd::CodeCompleteOptions Opts; + for( auto& testcase : { + R"cpp( + struct foo {}; + void bar() { + foo a; + a.^ + )cpp", + R"cpp( + template struct foo {}; + void bar() { + foo a; + a.^ + )cpp", + R"cpp( + template struct foo {}; template<> struct foo {}; + void bar() { + foo a; + a.^ + )cpp", + R"cpp( + struct foo {}; + void bar() { + foo* b; + b->^ + )cpp", + R"cpp( + template struct foo {}; + void bar() { + foo* b; + b->^ + )cpp", + R"cpp( + template struct foo {}; template<> struct foo {}; + void bar() { + foo* b; + b->^ + )cpp", + R"cpp( + struct foo {}; + foo::^ + )cpp", + R"cpp( + template struct foo {}; + foo::^ + )cpp", + R"cpp( + template struct foo {}; template<> struct foo {}; + foo::^ + )cpp", + R"cpp( + struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo a; + a.^ + )cpp", + R"cpp( + struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo* b; + b->^ + )cpp", + R"cpp( + struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + foo::^ + )cpp", + R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo a; + a.^ + )cpp", + R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo* b; + b->^ + )cpp", + R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + foo::^ + )cpp", + R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + template<> struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo a; + a.^ + )cpp", + R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + template<> struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + void bar() { + foo* b; + b->^ + )cpp", + R"cpp( + template struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + template<> struct foo { foo(); ~foo(); foo& operator=(const foo&); foo& operator=(foo&&); }; + foo::^ + )cpp" + }) { + auto Results = completions(testcase, /*IndexSymbols=*/{}, Opts); + EXPECT_THAT(Results.Completions, IsEmpty()) << testcase; + } +} + } // namespace } // namespace clangd } // namespace clang