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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits