From 1c92e06ded2da33f9ad00305af281e47cf9c584f Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Mon, 20 Jun 2022 15:23:32 +0200 Subject: [PATCH] [clangd] Handle initializers that contain = Differential Revision: https://reviews.llvm.org/D128197 --- .../clangd/refactor/tweaks/DefineOutline.cpp | 30 ++++++++++++---------- .../clangd/unittests/tweaks/DefineOutlineTests.cpp | 5 ++++ 2 files changed, 22 insertions(+), 13 deletions(-) diff --git a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp index 0bbf327..298546a 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/DefineOutline.cpp @@ -187,26 +187,30 @@ getFunctionSourceCode(const FunctionDecl *FD, llvm::StringRef TargetNamespace, // 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 spans the initializer, usually 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 index 3131e20..e3954e6 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/DefineOutlineTests.cpp @@ -116,6 +116,11 @@ TEST_F(DefineOutlineTest, ApplyTest) { "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( -- 2.7.4