Skip to content

Commit e8a2b7c

Browse files
committed
[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
1 parent 8cc9c42 commit e8a2b7c

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

clang-tools-extra/clangd/refactor/Rename.cpp

+17-3
Original file line numberDiff line numberDiff line change
@@ -337,9 +337,10 @@ const NamedDecl *lookupSiblingWithinEnclosingScope(ASTContext &Ctx,
337337
};
338338

339339
// We need to get to the enclosing scope: NamedDecl's parent is typically
340-
// DeclStmt, so enclosing scope would be the second order parent.
340+
// DeclStmt (or FunctionProtoTypeLoc in case of function arguments), so
341+
// enclosing scope would be the second order parent.
341342
const auto *Parent = GetSingleParent(DynTypedNode::create(RenamedDecl));
342-
if (!Parent || !Parent->get<DeclStmt>())
343+
if (!Parent || !(Parent->get<DeclStmt>() || Parent->get<TypeLoc>()))
343344
return nullptr;
344345
Parent = GetSingleParent(*Parent);
345346

@@ -407,8 +408,21 @@ const NamedDecl *lookupSiblingWithinEnclosingScope(ASTContext &Ctx,
407408
}
408409
if (const auto *EnclosingWhile = Parent->get<WhileStmt>())
409410
return CheckCompoundStmt(EnclosingWhile->getBody(), NewName);
410-
if (const auto *EnclosingFor = Parent->get<ForStmt>())
411+
if (const auto *EnclosingFor = Parent->get<ForStmt>()) {
412+
// Check for conflicts with other declarations within initialization
413+
// statement.
414+
if (const auto *Result = CheckDeclStmt(
415+
dyn_cast_or_null<DeclStmt>(EnclosingFor->getInit()), NewName))
416+
return Result;
411417
return CheckCompoundStmt(EnclosingFor->getBody(), NewName);
418+
}
419+
if (const auto *EnclosingFunction = Parent->get<FunctionDecl>()) {
420+
// Check for conflicts with other arguments.
421+
for (const auto *Parameter : EnclosingFunction->parameters())
422+
if (Parameter != &RenamedDecl && Parameter->getName() == NewName)
423+
return Parameter;
424+
return CheckCompoundStmt(EnclosingFunction->getBody(), NewName);
425+
}
412426

413427
return nullptr;
414428
}

clang-tools-extra/clangd/unittests/RenameTests.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -1067,13 +1067,34 @@ TEST(RenameTest, Renameable) {
10671067
)cpp",
10681068
"conflict", !HeaderFile, nullptr, "Conflict"},
10691069

1070+
{R"cpp(
1071+
void func() {
1072+
for (int V^ar = 14, Conflict = 42;;) {
1073+
}
1074+
}
1075+
)cpp",
1076+
"conflict", !HeaderFile, nullptr, "Conflict"},
1077+
10701078
{R"cpp(
10711079
void func(int Conflict) {
10721080
bool V^ar;
10731081
}
10741082
)cpp",
10751083
"conflict", !HeaderFile, nullptr, "Conflict"},
10761084

1085+
{R"cpp(
1086+
void func(int V^ar) {
1087+
bool Conflict;
1088+
}
1089+
)cpp",
1090+
"conflict", !HeaderFile, nullptr, "Conflict"},
1091+
1092+
{R"cpp(
1093+
void func(int V^ar, int Conflict) {
1094+
}
1095+
)cpp",
1096+
"conflict", !HeaderFile, nullptr, "Conflict"},
1097+
10771098
{R"cpp(// Trying to rename into the same name, SameName == SameName.
10781099
void func() {
10791100
int S^ameName;

0 commit comments

Comments
 (0)