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 @@ -187,26 +187,30 @@ // Get rid of default arguments, since they should not be specified in // out-of-line definition. for (const auto *PVD : FD->parameters()) { - if (PVD->hasDefaultArg()) { - // Deletion range initially spans the initializer, excluding the `=`. - auto DelRange = CharSourceRange::getTokenRange(PVD->getDefaultArgRange()); - // Get all tokens before the default argument. - auto Tokens = TokBuf.expandedTokens(PVD->getSourceRange()) - .take_while([&SM, &DelRange](const syntax::Token &Tok) { - return SM.isBeforeInTranslationUnit( - Tok.location(), DelRange.getBegin()); - }); - // Find the last `=` before the default arg. + if (!PVD->hasDefaultArg()) + continue; + // Deletion range initially spans the initializer, excluding the `=`. + auto DelRange = CharSourceRange::getTokenRange(PVD->getDefaultArgRange()); + // Get all tokens before the default argument. + auto Tokens = TokBuf.expandedTokens(PVD->getSourceRange()) + .take_while([&SM, &DelRange](const syntax::Token &Tok) { + return SM.isBeforeInTranslationUnit( + Tok.location(), DelRange.getBegin()); + }); + if (TokBuf.expandedTokens(DelRange.getAsRange()).front().kind() != + tok::equal) { + // Find the last `=` if it isn't included in the initializer, and update + // the DelRange to include it. auto Tok = llvm::find_if(llvm::reverse(Tokens), [](const syntax::Token &Tok) { return Tok.kind() == tok::equal; }); assert(Tok != Tokens.rend()); DelRange.setBegin(Tok->location()); - if (auto Err = - DeclarationCleanups.add(tooling::Replacement(SM, DelRange, ""))) - Errors = llvm::joinErrors(std::move(Errors), std::move(Err)); } + if (auto Err = + DeclarationCleanups.add(tooling::Replacement(SM, DelRange, ""))) + Errors = llvm::joinErrors(std::move(Errors), std::move(Err)); } auto DelAttr = [&](const Attr *A) { 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 @@ -116,6 +116,11 @@ "void foo(int x, int y = 5, int = 2, int (*foo)(int) = nullptr) ;", "void foo(int x, int y , int , int (*foo)(int) ) {}", }, + { + "struct Bar{Bar();}; void fo^o(Bar x = {}) {}", + "struct Bar{Bar();}; void foo(Bar x = {}) ;", + "void foo(Bar x ) {}", + }, // Constructors { R"cpp(