diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp --- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -183,6 +183,20 @@ }, Resolver); + // findExplicitReferences doesn't provide references to + // constructor/destructors, it only provides references to type names inside + // them. + // this works for constructors, but doesn't work for destructor as type name + // doesn't cover leading `~`, so handle it specially. + if (const auto *Destructor = llvm::dyn_cast(FD)) { + if (auto Err = DeclarationCleanups.add(tooling::Replacement( + SM, Destructor->getLocation(), 0, + getQualification(AST, *TargetContext, + SM.getLocForStartOfFile(SM.getMainFileID()), + Destructor)))) + Errors = llvm::joinErrors(std::move(Errors), std::move(Err)); + } + // Get rid of default arguments, since they should not be specified in // out-of-line definition. for (const auto *PVD : FD->parameters()) { diff --git a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp --- a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp @@ -319,6 +319,12 @@ };)cpp", " Foo::Foo(int) {}\n", }, + // Destrctors + { + "class A { ~A^(){} };", + "class A { ~A(); };", + "A::~A(){} ", + }, }; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Test); @@ -532,6 +538,18 @@ // account. This can be spelled as b::foo instead. "using namespace a;void a::b::foo() {} ", }, + { + "namespace a { class A { ~A^(){} }; }", + "", + "namespace a { class A { ~A(); }; }", + "a::A::~A(){} ", + }, + { + "namespace a { class A { ~A^(){} }; }", + "namespace a{}", + "namespace a { class A { ~A(); }; }", + "namespace a{A::~A(){} }", + }, }; llvm::StringMap EditedFiles; for (auto &Case : Cases) {