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 @@ -151,6 +151,20 @@ if (const auto *VD = dyn_cast(D)) { if (const VarDecl *OriginalVD = VD->getInstantiatedFromStaticDataMember()) VD = OriginalVD; + // Arguments are canonicalized to their function's canonical function + // arguments. + if (const auto *Argument = dyn_cast(VD)) { + if (const auto *Function = + dyn_cast(Argument->getDeclContext())) { + // FIXME(kirillbobyrev): This excludes constructors: their canonical + // decls are canonicalized RecordDecls. + if (const auto *Canonical = + dyn_cast(canonicalRenameDecl(Function))) { + return Canonical->getParamDecl(Argument->getFunctionScopeIndex()) + ->getCanonicalDecl(); + } + } + } return VD->getCanonicalDecl(); } return dyn_cast(D->getCanonicalDecl()); 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 @@ -678,6 +678,34 @@ } )cpp", + // Function argument. + R"cpp( + void foo(int [[Bar^]]); + void foo(int [[Bar^]]); + + void foo(int [[Bar^]]) { + } + )cpp", + + // Template function argument. + R"cpp( + template + void foo(T [[Bar^]]); + + template + void foo(T [[Bar^]]) {} + )cpp", + R"cpp( + template + void foo(T [[Bar^]]); + + template + void foo(T [[Bar^]]) {} + + template <> + void foo(int [[Bar^]]) {} + )cpp", + // Namespace alias. R"cpp( namespace a { namespace b { void foo(); } } @@ -1089,6 +1117,15 @@ )cpp", "conflict", !HeaderFile, nullptr, "Conflict"}, + {R"cpp( + void func(int V^ar); + + void func(int Var) { + bool Conflict; + } + )cpp", + "conflict", !HeaderFile, nullptr, "Conflict"}, + {R"cpp( void func(int V^ar, int Conflict) { }