diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index d10103752d81f7..5f35257390912c 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -3095,7 +3095,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl { /// Retrieve the set of partial specializations of this class /// template. llvm::FoldingSetVector & - getPartialSpecializations(); + getPartialSpecializations() const; VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, @@ -3191,7 +3191,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl { /// Retrieve the partial specializations as an ordered list. void getPartialSpecializations( - SmallVectorImpl &PS); + SmallVectorImpl &PS) const; /// Find a variable template partial specialization which was /// instantiated diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 5538651a453d40..d99a9c19c506e2 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -1142,7 +1142,7 @@ VarTemplateDecl::getSpecializations() const { } llvm::FoldingSetVector & -VarTemplateDecl::getPartialSpecializations() { +VarTemplateDecl::getPartialSpecializations() const { LoadLazySpecializations(); return getCommonPtr()->PartialSpecializations; } @@ -1198,7 +1198,7 @@ void VarTemplateDecl::AddPartialSpecialization( } void VarTemplateDecl::getPartialSpecializations( - SmallVectorImpl &PS) { + SmallVectorImpl &PS) const { llvm::FoldingSetVector &PartialSpecs = getPartialSpecializations(); PS.clear(); diff --git a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp index e4056f701683a5..a69b76a3c9712e 100644 --- a/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp +++ b/clang/lib/Tooling/Refactoring/Rename/USRFindingAction.cpp @@ -86,6 +86,16 @@ class AdditionalUSRFinder : public RecursiveASTVisitor { handleFunctionTemplateDecl(FTD); } else if (const auto *FD = dyn_cast(FoundDecl)) { handleFunctionTemplateDecl(FD); + } else if (const auto *VTD = dyn_cast(FoundDecl)) { + handleVarTemplateDecl(VTD); + } else if (const auto *VD = + dyn_cast(FoundDecl)) { + // FIXME: figure out why FoundDecl can be a VarTemplateSpecializationDecl. + handleVarTemplateDecl(VD->getSpecializedTemplate()); + } else if (const auto *VD = dyn_cast(FoundDecl)) { + USRSet.insert(getUSRForDecl(VD)); + if (const auto *VTD = VD->getDescribedVarTemplate()) + handleVarTemplateDecl(VTD); } else { USRSet.insert(getUSRForDecl(FoundDecl)); } @@ -132,6 +142,19 @@ class AdditionalUSRFinder : public RecursiveASTVisitor { USRSet.insert(getUSRForDecl(S)); } + void handleVarTemplateDecl(const VarTemplateDecl *VTD) { + USRSet.insert(getUSRForDecl(VTD)); + USRSet.insert(getUSRForDecl(VTD->getTemplatedDecl())); + llvm::for_each(VTD->specializations(), [&](const auto *Spec) { + USRSet.insert(getUSRForDecl(Spec)); + }); + SmallVector PartialSpecs; + VTD->getPartialSpecializations(PartialSpecs); + llvm::for_each(PartialSpecs, [&](const auto *Spec) { + USRSet.insert(getUSRForDecl(Spec)); + }); + } + void addUSRsOfCtorDtors(const CXXRecordDecl *RD) { const auto* RecordDecl = RD->getDefinition(); diff --git a/clang/test/clang-rename/VariableTemplate.cpp b/clang/test/clang-rename/VariableTemplate.cpp new file mode 100644 index 00000000000000..a345ede5a7f6ad --- /dev/null +++ b/clang/test/clang-rename/VariableTemplate.cpp @@ -0,0 +1,32 @@ +template +bool Foo = true; // CHECK: bool Bar = true; + +// explicit template specialization +template <> +bool Foo = false; // CHECK: bool Bar = false; + +// partial template specialization +template +bool Foo = false; // bool Bar = false; + +void k() { + // ref to the explicit template specialization + Foo; // CHECK: Bar; + // ref to the primary template. + Foo; // CHECK: Bar; +} + + +// Test 1. +// RUN: clang-rename -offset=34 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s +// Test 2. +// RUN: clang-rename -offset=128 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s +// Test 3. +// RUN: clang-rename -offset=248 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s +// Test 4. +// RUN: clang-rename -offset=357 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s +// Test 5. +// RUN: clang-rename -offset=431 -new-name=Bar %s -- | sed 's,//.*,,' | FileCheck %s + +// To find offsets after modifying the file, use: +// grep -Ubo 'Foo.*'