[clang-tools-extra] 04f4c4c - [clangd] Move function body to out-of-line: unnamed class method incorrect moving

Denis Fatkulin via cfe-commits cfe-commits at lists.llvm.org
Fri Feb 10 06:40:42 PST 2023


Author: Denis Fatkulin
Date: 2023-02-10T17:40:21+03:00
New Revision: 04f4c4cc59db0f4db9cddcc5846d98491d4b65f5

URL: https://github.com/llvm/llvm-project/commit/04f4c4cc59db0f4db9cddcc5846d98491d4b65f5
DIFF: https://github.com/llvm/llvm-project/commit/04f4c4cc59db0f4db9cddcc5846d98491d4b65f5.diff

LOG: [clangd] Move function body to out-of-line: unnamed class method incorrect moving

The refactoring !!Move function body to out-of-line!! produces incorrect code for methods of unnamed classes.
For this simple example
  // foo.h
  struct Foo {
    struct {
      void f^oo() {}
    } Bar;
  };

the refactoring generates code:
  // foo.cpp
  void Foo::(unnamed struct at D:\test\foo.h:2:3)foo() {}

Outplace definition for methods of unnamed classes is meaningless. The patch disables it.

Reviewed By: kadircet

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

Added: 
    

Modified: 
    clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
    clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
index a4d60c6c11bb9..95334c49bfb6e 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp
@@ -392,11 +392,20 @@ class DefineOutline : public Tweak {
     if (Source->getTemplateSpecializationInfo())
       return false;
 
-    // Bail out in templated classes, as it is hard to spell the class name, i.e
-    // if the template parameter is unnamed.
     if (auto *MD = llvm::dyn_cast<CXXMethodDecl>(Source)) {
+      // Bail out in templated classes, as it is hard to spell the class name,
+      // i.e if the template parameter is unnamed.
       if (MD->getParent()->isTemplated())
         return false;
+
+      // The refactoring is meaningless for unnamed classes and definitions
+      // within unnamed namespaces.
+      for (const DeclContext *DC = MD->getParent(); DC; DC = DC->getParent()) {
+        if (auto *ND = llvm::dyn_cast<NamedDecl>(DC)) {
+          if (ND->getDeclName().isEmpty())
+            return false;
+        }
+      }
     }
 
     // Note that we don't check whether an implementation file exists or not in

diff  --git a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
index e3954e6b2faff..c6c9684ffa4fa 100644
--- a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
+++ b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp
@@ -84,6 +84,32 @@ TEST_F(DefineOutlineTest, TriggersOnFunctionDecl) {
     template <typename> void fo^o() {};
     template <> void fo^o<int>() {};
   )cpp");
+
+  // Not available on methods of unnamed classes.
+  EXPECT_UNAVAILABLE(R"cpp(
+    struct Foo {
+      struct { void b^ar() {} } Bar;
+    };
+  )cpp");
+
+  // Not available on methods of named classes with unnamed parent in parents
+  // nesting.
+  EXPECT_UNAVAILABLE(R"cpp(
+    struct Foo {
+      struct {
+        struct Bar { void b^ar() {} };
+      } Baz;
+    };
+  )cpp");
+
+  // Not available on definitions within unnamed namespaces
+  EXPECT_UNAVAILABLE(R"cpp(
+    namespace {
+      struct Foo {
+        void f^oo() {}
+      };
+    } // namespace
+  )cpp");
 }
 
 TEST_F(DefineOutlineTest, FailsWithoutSource) {


        


More information about the cfe-commits mailing list