denis-fatkulin created this revision. denis-fatkulin added reviewers: kadircet, sammccall. Herald added a subscriber: arphaman. Herald added a project: All. denis-fatkulin requested review of this revision. Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov. Herald added a project: clang-tools-extra.
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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D143638 Files: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp Index: clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp +++ clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp @@ -84,6 +84,23 @@ 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"); } TEST_F(DefineOutlineTest, FailsWithoutSource) { Index: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp =================================================================== --- clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -397,6 +397,14 @@ if (auto *MD = llvm::dyn_cast<CXXMethodDecl>(Source)) { if (MD->getParent()->isTemplated()) return false; + + // The refactoring is meaningless for unnamed classes. + const auto *Parent = MD->getParent(); + while (Parent) { + if (Parent->getName().empty()) + return false; + Parent = llvm::dyn_cast_or_null<CXXRecordDecl>(Parent->getParent()); + } } // Note that we don't check whether an implementation file exists or not in
Index: clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp +++ clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp @@ -84,6 +84,23 @@ 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"); } TEST_F(DefineOutlineTest, FailsWithoutSource) { Index: clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp =================================================================== --- clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -397,6 +397,14 @@ if (auto *MD = llvm::dyn_cast<CXXMethodDecl>(Source)) { if (MD->getParent()->isTemplated()) return false; + + // The refactoring is meaningless for unnamed classes. + const auto *Parent = MD->getParent(); + while (Parent) { + if (Parent->getName().empty()) + return false; + Parent = llvm::dyn_cast_or_null<CXXRecordDecl>(Parent->getParent()); + } } // Note that we don't check whether an implementation file exists or not in
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits