njames93 updated this revision to Diff 513862. njames93 edited the summary of this revision. njames93 added a comment.
Fix unittest, tests had trivial and non trivial mixed up Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D147808/new/ https://reviews.llvm.org/D147808 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 @@ -110,6 +110,16 @@ }; } // namespace )cpp"); + + // Not available on trivially defaulted functions + EXPECT_UNAVAILABLE( R"cpp( + struct A { + A^() = default; + };)cpp"); + EXPECT_UNAVAILABLE( R"cpp( + struct A { + ~A^() = default; + };)cpp"); } TEST_F(DefineOutlineTest, FailsWithoutSource) { @@ -325,6 +335,37 @@ "class A { ~A(); };", "A::~A(){} ", }, + // Defaulted Functions + { + R"cpp( + struct A { A (); }; + struct B { + A a; + B^() = default; + };)cpp", + R"cpp( + struct A { A (); }; + struct B { + A a; + B() ; + };)cpp", + "B::B() = default;", + }, + { + R"cpp( + struct A { ~A (); }; + struct B { + A a; + ~B^() = default; + };)cpp", + R"cpp( + struct A { ~A (); }; + struct B { + A a; + ~B() ; + };)cpp", + "B::~B() = default;", + }, }; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Test); 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 @@ -325,6 +325,14 @@ // initializers. SourceRange getDeletionRange(const FunctionDecl *FD, const syntax::TokenBuffer &TokBuf) { + if (FD->isExplicitlyDefaulted()) { + auto Toks = + TokBuf.expandedTokens({FD->getTypeSpecEndLoc(), FD->getDefaultLoc()}); + Toks = Toks.drop_until( + [](const syntax::Token &Tok) { return Tok.kind() == tok::equal; }); + assert(Toks.size() == 2); + return {Toks.front().location(), Toks.back().endLocation()}; + } auto DeletionRange = FD->getBody()->getSourceRange(); if (auto *CD = llvm::dyn_cast<CXXConstructorDecl>(FD)) { // AST doesn't contain the location for ":" in ctor initializers. Therefore @@ -395,7 +403,10 @@ Source = getSelectedFunction(Sel.ASTSelection.commonAncestor()); // Bail out if the selection is not a in-line function definition. - if (!Source || !Source->doesThisDeclarationHaveABody() || + // unless its a not-trivial special member function + if (!Source || + (!Source->doesThisDeclarationHaveABody() && + (!Source->isExplicitlyDefaulted() || Source->isTrivial())) || Source->isOutOfLine()) return false;
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 @@ -110,6 +110,16 @@ }; } // namespace )cpp"); + + // Not available on trivially defaulted functions + EXPECT_UNAVAILABLE( R"cpp( + struct A { + A^() = default; + };)cpp"); + EXPECT_UNAVAILABLE( R"cpp( + struct A { + ~A^() = default; + };)cpp"); } TEST_F(DefineOutlineTest, FailsWithoutSource) { @@ -325,6 +335,37 @@ "class A { ~A(); };", "A::~A(){} ", }, + // Defaulted Functions + { + R"cpp( + struct A { A (); }; + struct B { + A a; + B^() = default; + };)cpp", + R"cpp( + struct A { A (); }; + struct B { + A a; + B() ; + };)cpp", + "B::B() = default;", + }, + { + R"cpp( + struct A { ~A (); }; + struct B { + A a; + ~B^() = default; + };)cpp", + R"cpp( + struct A { ~A (); }; + struct B { + A a; + ~B() ; + };)cpp", + "B::~B() = default;", + }, }; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Test); 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 @@ -325,6 +325,14 @@ // initializers. SourceRange getDeletionRange(const FunctionDecl *FD, const syntax::TokenBuffer &TokBuf) { + if (FD->isExplicitlyDefaulted()) { + auto Toks = + TokBuf.expandedTokens({FD->getTypeSpecEndLoc(), FD->getDefaultLoc()}); + Toks = Toks.drop_until( + [](const syntax::Token &Tok) { return Tok.kind() == tok::equal; }); + assert(Toks.size() == 2); + return {Toks.front().location(), Toks.back().endLocation()}; + } auto DeletionRange = FD->getBody()->getSourceRange(); if (auto *CD = llvm::dyn_cast<CXXConstructorDecl>(FD)) { // AST doesn't contain the location for ":" in ctor initializers. Therefore @@ -395,7 +403,10 @@ Source = getSelectedFunction(Sel.ASTSelection.commonAncestor()); // Bail out if the selection is not a in-line function definition. - if (!Source || !Source->doesThisDeclarationHaveABody() || + // unless its a not-trivial special member function + if (!Source || + (!Source->doesThisDeclarationHaveABody() && + (!Source->isExplicitlyDefaulted() || Source->isTrivial())) || Source->isOutOfLine()) return false;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits