[clang-tools-extra] 46575f6 - [clangd] Fix action `RemoveUsingNamespace` for inline namespace

Tom Praschan via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 28 03:49:57 PST 2022


Author: v1nh1shungry
Date: 2022-12-28T13:34:43+01:00
New Revision: 46575f60380b18bf20c5f4cafc5fd06f561c4e7b

URL: https://github.com/llvm/llvm-project/commit/46575f60380b18bf20c5f4cafc5fd06f561c4e7b
DIFF: https://github.com/llvm/llvm-project/commit/46575f60380b18bf20c5f4cafc5fd06f561c4e7b.diff

LOG: [clangd] Fix action `RemoveUsingNamespace` for inline namespace

Existing version ignores symbols declared in an inline namespace `ns`
when removing `using namespace ns`

Reviewed By: tom-anders

Differential Revision: https://reviews.llvm.org/D138028

Added: 
    

Modified: 
    clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp
    clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp b/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp
index f4228ae0be1f..ec02beb7e46f 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp
@@ -89,16 +89,15 @@ bool isTopLevelDecl(const SelectionTree::Node *Node) {
   return Node->Parent && Node->Parent->ASTNode.get<TranslationUnitDecl>();
 }
 
-// Returns the first visible context that contains this DeclContext.
-// For example: Returns ns1 for S1 and a.
-// namespace ns1 {
-// inline namespace ns2 { struct S1 {}; }
-// enum E { a, b, c, d };
-// }
-const DeclContext *visibleContext(const DeclContext *D) {
-  while (D->isInlineNamespace() || D->isTransparentContext())
+// Return true if `LHS` is declared in `RHS`
+bool isDeclaredIn(const NamedDecl *LHS, const DeclContext *RHS) {
+  const auto *D = LHS->getDeclContext();
+  while (D->isInlineNamespace() || D->isTransparentContext()) {
+    if (D->Equals(RHS))
+      return true;
     D = D->getParent();
-  return D;
+  }
+  return D->Equals(RHS);
 }
 
 bool RemoveUsingNamespace::prepare(const Selection &Inputs) {
@@ -152,8 +151,7 @@ Expected<Tweak::Effect> RemoveUsingNamespace::apply(const Selection &Inputs) {
             return; // This reference is already qualified.
 
           for (auto *T : Ref.Targets) {
-            if (!visibleContext(T->getDeclContext())
-                     ->Equals(TargetDirective->getNominatedNamespace()))
+            if (!isDeclaredIn(T, TargetDirective->getNominatedNamespace()))
               return;
             auto Kind = T->getDeclName().getNameKind();
             // Avoid adding qualifiers before operators, e.g.

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp
index 03a46d954fcd..b0311534d6d8 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp
@@ -264,6 +264,17 @@ TEST_F(RemoveUsingNamespaceTest, All) {
       }
       
       int main() { 1.5_w; }
+    )cpp"},
+      {
+          R"cpp(
+      namespace a { inline namespace b { void foobar(); } }
+      using namespace a::[[b]];
+      int main() { foobar(); }
+    )cpp",
+          R"cpp(
+      namespace a { inline namespace b { void foobar(); } }
+      
+      int main() { a::b::foobar(); }
     )cpp"}};
   for (auto C : Cases)
     EXPECT_EQ(C.second, apply(C.first)) << C.first;


        


More information about the cfe-commits mailing list