From f5a2ef80fa47d657877d5be314ce29ff7195d887 Mon Sep 17 00:00:00 2001 From: v1nh1shungry Date: Sun, 6 Nov 2022 18:30:41 +0100 Subject: [PATCH] [clangd] Fix the code action `RemoveUsingNamespace` Avoid adding qualifiers before C++ operators declared in a non-class context Reviewed By: tom-anders Differential Revision: https://reviews.llvm.org/D137494 --- .../refactor/tweaks/RemoveUsingNamespace.cpp | 7 +++++++ .../unittests/tweaks/RemoveUsingNamespaceTests.cpp | 23 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp b/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp index 8df7a44..93fdbb9 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp @@ -155,6 +155,13 @@ Expected RemoveUsingNamespace::apply(const Selection &Inputs) { if (!visibleContext(T->getDeclContext()) ->Equals(TargetDirective->getNominatedNamespace())) return; + // Avoid adding qualifiers before operators, e.g. + // using namespace std; + // cout << "foo"; // Must not changed to std::cout std:: << "foo" + // FIXME: User-defined literals are not handled + if (T->isInIdentifierNamespace( + Decl::IdentifierNamespace::IDNS_NonMemberOperator)) + return; } SourceLocation Loc = Ref.NameLoc; if (Loc.isMacroID()) { diff --git a/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp index 59788e7..3449c64 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp @@ -226,6 +226,29 @@ TEST_F(RemoveUsingNamespaceTest, All) { int main() { std::vector V; } + )cpp"}, + {// Does not qualify operators declared in a non-class context + R"cpp( + namespace ns { + struct Foo {}; + void operator+(const Foo &, int) {} + } + using namespace n^s; + int main() { + Foo foo; + foo + 10; + } + )cpp", + R"cpp( + namespace ns { + struct Foo {}; + void operator+(const Foo &, int) {} + } + + int main() { + ns::Foo foo; + foo + 10; + } )cpp"}}; for (auto C : Cases) EXPECT_EQ(C.second, apply(C.first)) << C.first; -- 2.7.4