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 @@ -137,6 +137,17 @@ }; )cpp", + // Rename template class constructor. + R"cpp( + class [[F^oo]] { + template + [[Foo]](); + + template + [[Foo]](T t); + }; + )cpp", + // Class in template argument. R"cpp( class [[F^oo]] {}; diff --git a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp --- a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp +++ b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp @@ -135,6 +135,13 @@ for (const auto *CtorDecl : RecordDecl->ctors()) USRSet.insert(getUSRForDecl(CtorDecl)); + // Add template constructor decls, they are not in ctors() unfortunately. + if (RecordDecl->hasUserDeclaredConstructor()) + for (const auto *MD : RecordDecl->decls()) + if (const auto *FTD = dyn_cast(MD)) + if (const auto *Ctor = + dyn_cast(FTD->getTemplatedDecl())) + USRSet.insert(getUSRForDecl(Ctor)); USRSet.insert(getUSRForDecl(RecordDecl->getDestructor())); USRSet.insert(getUSRForDecl(RecordDecl)); diff --git a/clang/test/clang-rename/TemplateCtor.cpp b/clang/test/clang-rename/TemplateCtor.cpp new file mode 100644 --- /dev/null +++ b/clang/test/clang-rename/TemplateCtor.cpp @@ -0,0 +1,10 @@ +class Foo { // CHECK: class Bar { +public: + template + Foo(); // CHECK: Bar(); + + template + Foo(Foo &); // CHECK: Bar(Bar &); +}; + +// RUN: clang-rename -offset=6 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s