diff --git a/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp b/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp @@ -155,6 +155,13 @@ 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 --- a/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp @@ -226,7 +226,30 @@ int main() { std::vector V; } - )cpp"}}; + )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; }