Author: Kirill Bobyrev Date: 2021-02-04T21:37:41+01:00 New Revision: e8a2b7c91563169b68d2a878c65deecc85ced466
URL: https://github.com/llvm/llvm-project/commit/e8a2b7c91563169b68d2a878c65deecc85ced466 DIFF: https://github.com/llvm/llvm-project/commit/e8a2b7c91563169b68d2a878c65deecc85ced466.diff LOG: [clangd] Improve name conflict detection Follow-up on D95925: adds better detection for function arguments and also checks for conflicts in muli-variable init statements in ForStmt. Reviewed By: hokein Differential Revision: https://reviews.llvm.org/D96009 Added: Modified: clang-tools-extra/clangd/refactor/Rename.cpp clang-tools-extra/clangd/unittests/RenameTests.cpp Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/refactor/Rename.cpp b/clang-tools-extra/clangd/refactor/Rename.cpp index bcce307a4362..07422a06a923 100644 --- a/clang-tools-extra/clangd/refactor/Rename.cpp +++ b/clang-tools-extra/clangd/refactor/Rename.cpp @@ -337,9 +337,10 @@ const NamedDecl *lookupSiblingWithinEnclosingScope(ASTContext &Ctx, }; // 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 FunctionProtoTypeLoc 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<DeclStmt>()) + if (!Parent || !(Parent->get<DeclStmt>() || Parent->get<TypeLoc>())) return nullptr; Parent = GetSingleParent(*Parent); @@ -407,8 +408,21 @@ const NamedDecl *lookupSiblingWithinEnclosingScope(ASTContext &Ctx, } if (const auto *EnclosingWhile = Parent->get<WhileStmt>()) return CheckCompoundStmt(EnclosingWhile->getBody(), NewName); - if (const auto *EnclosingFor = Parent->get<ForStmt>()) + if (const auto *EnclosingFor = Parent->get<ForStmt>()) { + // Check for conflicts with other declarations within initialization + // statement. + if (const auto *Result = CheckDeclStmt( + dyn_cast_or_null<DeclStmt>(EnclosingFor->getInit()), NewName)) + return Result; return CheckCompoundStmt(EnclosingFor->getBody(), NewName); + } + if (const auto *EnclosingFunction = Parent->get<FunctionDecl>()) { + // 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 index 4678d35199f1..78b2af6f8cfc 100644 --- a/clang-tools-extra/clangd/unittests/RenameTests.cpp +++ b/clang-tools-extra/clangd/unittests/RenameTests.cpp @@ -1067,6 +1067,14 @@ TEST(RenameTest, Renameable) { )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 @@ TEST(RenameTest, Renameable) { )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; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits