diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp b/clang-tools-extra/clangd/refactor/Rename.cpp --- a/clang-tools-extra/clangd/refactor/Rename.cpp +++ b/clang-tools-extra/clangd/refactor/Rename.cpp @@ -337,9 +337,10 @@ }; // We need to get to the enclosing scope: NamedDecl's parent is typically - // DeclStmt, so enclosing scope would be the second order parent. + // DeclStmt (or TypeLoc in case of function arguments), so enclosing scope + // would be the second order parent. const auto *Parent = GetSingleParent(DynTypedNode::create(RenamedDecl)); - if (!Parent || !Parent->get()) + if (!Parent || !(Parent->get() || Parent->get())) return nullptr; Parent = GetSingleParent(*Parent); @@ -407,8 +408,21 @@ } if (const auto *EnclosingWhile = Parent->get()) return CheckCompoundStmt(EnclosingWhile->getBody(), NewName); - if (const auto *EnclosingFor = Parent->get()) + if (const auto *EnclosingFor = Parent->get()) { + // Check for conflicts with other declarations within initialization + // statement. + if (const auto *Result = CheckDeclStmt( + dyn_cast_or_null(EnclosingFor->getInit()), NewName)) + return Result; return CheckCompoundStmt(EnclosingFor->getBody(), NewName); + } + if (const auto *EnclosingFunction = Parent->get()) { + // Check for conflicts with other arguments. + for (const auto *Parameter : EnclosingFunction->parameters()) + if (Parameter != &RenamedDecl && Parameter->getName() == NewName) + return Parameter; + return CheckCompoundStmt(EnclosingFunction->getBody(), NewName); + } return nullptr; } diff --git a/clang-tools-extra/clangd/unittests/RenameTests.cpp b/clang-tools-extra/clangd/unittests/RenameTests.cpp --- a/clang-tools-extra/clangd/unittests/RenameTests.cpp +++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp @@ -1067,6 +1067,14 @@ )cpp", "conflict", !HeaderFile, nullptr, "Conflict"}, + {R"cpp( + void func() { + for (int V^ar = 14, Conflict = 42;;) { + } + } + )cpp", + "conflict", !HeaderFile, nullptr, "Conflict"}, + {R"cpp( void func(int Conflict) { bool V^ar; @@ -1074,6 +1082,19 @@ )cpp", "conflict", !HeaderFile, nullptr, "Conflict"}, + {R"cpp( + void func(int V^ar) { + bool Conflict; + } + )cpp", + "conflict", !HeaderFile, nullptr, "Conflict"}, + + {R"cpp( + void func(int V^ar, int Conflict) { + } + )cpp", + "conflict", !HeaderFile, nullptr, "Conflict"}, + {R"cpp(// Trying to rename into the same name, SameName == SameName. void func() { int S^ameName;