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 @@ -80,6 +80,12 @@ } else if (const auto *TemplateDecl = dyn_cast(FoundDecl)) { handleClassTemplateDecl(TemplateDecl); + } else if (const auto *FD = dyn_cast(FoundDecl)) { + USRSet.insert(getUSRForDecl(FD)); + if (const auto *FTD = FD->getPrimaryTemplate()) + handleFunctionTemplateDecl(FTD); + } else if (const auto *FD = dyn_cast(FoundDecl)) { + handleFunctionTemplateDecl(FD); } else { USRSet.insert(getUSRForDecl(FoundDecl)); } @@ -119,6 +125,13 @@ addUSRsOfCtorDtors(TemplateDecl->getTemplatedDecl()); } + void handleFunctionTemplateDecl(const FunctionTemplateDecl *FTD) { + USRSet.insert(getUSRForDecl(FTD)); + USRSet.insert(getUSRForDecl(FTD->getTemplatedDecl())); + for (const auto *S : FTD->specializations()) + USRSet.insert(getUSRForDecl(S)); + } + void addUSRsOfCtorDtors(const CXXRecordDecl *RD) { const auto* RecordDecl = RD->getDefinition(); diff --git a/clang/test/clang-rename/FunctionTemplate.cpp b/clang/test/clang-rename/FunctionTemplate.cpp new file mode 100644 --- /dev/null +++ b/clang/test/clang-rename/FunctionTemplate.cpp @@ -0,0 +1,19 @@ +template +void Foo(T t); // CHECK: void Bar(T t); + +template <> +void Foo(int a); // CHECK: void Bar(int a); + +void test() { + Foo(1); // CHECK: Bar(1); +} + +// Test 1. +// RUN: clang-rename -offset=28 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s +// Test 2. +// RUN: clang-rename -offset=81 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s +// Test 3. +// RUN: clang-rename -offset=137 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s + +// To find offsets after modifying the file, use: +// grep -Ubo 'Foo.*'