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 @@ -16,6 +16,7 @@ #include "SourceCode.h" #include "refactor/Tweak.h" #include "clang/AST/ASTTypeTraits.h" +#include "clang/AST/Attr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" @@ -211,6 +212,18 @@ } } + // Removes the override specifier if it exists as it doesn't belong in the + // function out-of-line definition. + if (FD->hasAttr()) { + const auto *Override = FD->getAttr(); + assert(Override); + CharSourceRange DelRange = + CharSourceRange::getTokenRange(Override->getLocation()); + if (auto Err = + QualifierInsertions.add(tooling::Replacement(SM, DelRange, ""))) + Errors = llvm::joinErrors(std::move(Errors), std::move(Err)); + } + if (Errors) return std::move(Errors); return getFunctionSourceAfterReplacements(FD, QualifierInsertions); diff --git a/clang-tools-extra/clangd/unittests/TweakTests.cpp b/clang-tools-extra/clangd/unittests/TweakTests.cpp --- a/clang-tools-extra/clangd/unittests/TweakTests.cpp +++ b/clang-tools-extra/clangd/unittests/TweakTests.cpp @@ -2068,6 +2068,24 @@ };)cpp", "Foo::Foo(int z) __attribute__((weak)) : bar(2){}\n", }, + // Overridden Methods + { + R"cpp( + struct A { + virtual void foo() = 0; + }; + struct B : A { + void fo^o() override {} + };)cpp", + R"cpp( + struct A { + virtual void foo() = 0; + }; + struct B : A { + void foo() override ; + };)cpp", + "void B::foo() {}\n", + }, }; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Test);