aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorKrystian Stasiowski <sdkrystian@gmail.com>2024-10-08 08:14:09 -0600
committerGitHub <noreply@github.com>2024-10-08 10:14:09 -0400
commit4da8ac34f76e707ab94380b94f616457cfd2cb83 (patch)
tree1cf3da8bacc8d5a16188f8aaa0fa5f7574838cc1 /clang/lib/Sema/SemaDecl.cpp
parent148a8fef10031a5df5dac5de9bde9ddc4735ab9c (diff)
downloadllvm-4da8ac34f76e707ab94380b94f616457cfd2cb83.zip
llvm-4da8ac34f76e707ab94380b94f616457cfd2cb83.tar.gz
llvm-4da8ac34f76e707ab94380b94f616457cfd2cb83.tar.bz2
Reapply "[Clang][Sema] Refactor collection of multi-level template argument lists (#106585)" (#111173)
Reapplies #106585, fixing an issue where non-dependent names of member templates appearing prior to that member template being explicitly specialized for an implicitly instantiated class template specialization would incorrectly use the definition of the explicitly specialized member template.
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp31
1 files changed, 14 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4eaa391..83d7191 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -4510,10 +4510,10 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
adjustDeclContextForDeclaratorDecl(New, Old);
// Ensure the template parameters are compatible.
- if (NewTemplate &&
- !TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
- OldTemplate->getTemplateParameters(),
- /*Complain=*/true, TPL_TemplateMatch))
+ if (NewTemplate && !TemplateParameterListsAreEqual(
+ NewTemplate, NewTemplate->getTemplateParameters(),
+ OldTemplate, OldTemplate->getTemplateParameters(),
+ /*Complain=*/true, TPL_TemplateMatch))
return New->setInvalidDecl();
// C++ [class.mem]p1:
@@ -7663,7 +7663,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
: SourceLocation();
DeclResult Res = ActOnVarTemplateSpecialization(
S, D, TInfo, Previous, TemplateKWLoc, TemplateParams, SC,
- IsPartialSpecialization);
+ IsPartialSpecialization, IsMemberSpecialization);
if (Res.isInvalid())
return nullptr;
NewVD = cast<VarDecl>(Res.get());
@@ -7682,6 +7682,10 @@ NamedDecl *Sema::ActOnVariableDeclarator(
VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name,
TemplateParams, NewVD);
NewVD->setDescribedVarTemplate(NewTemplate);
+ // If we are providing an explicit specialization of a static variable
+ // template, make a note of that.
+ if (IsMemberSpecialization)
+ NewTemplate->setMemberSpecialization();
}
// If this decl has an auto type in need of deduction, make a note of the
@@ -8058,12 +8062,6 @@ NamedDecl *Sema::ActOnVariableDeclarator(
? TPC_ClassTemplateMember
: TPC_VarTemplate))
NewVD->setInvalidDecl();
-
- // If we are providing an explicit specialization of a static variable
- // template, make a note of that.
- if (PrevVarTemplate &&
- PrevVarTemplate->getInstantiatedFromMemberTemplate())
- PrevVarTemplate->setMemberSpecialization();
}
}
@@ -9870,6 +9868,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
NewFD);
FunctionTemplate->setLexicalDeclContext(CurContext);
NewFD->setDescribedFunctionTemplate(FunctionTemplate);
+ if (isMemberSpecialization)
+ FunctionTemplate->setMemberSpecialization();
// For source fidelity, store the other template param lists.
if (TemplateParamLists.size() > 1) {
@@ -12027,10 +12027,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// If this is an explicit specialization of a member that is a function
// template, mark it as a member specialization.
- if (IsMemberSpecialization &&
- NewTemplateDecl->getInstantiatedFromMemberTemplate()) {
- NewTemplateDecl->setMemberSpecialization();
- assert(OldTemplateDecl->isMemberSpecialization());
+ if (IsMemberSpecialization) {
// Explicit specializations of a member template do not inherit deleted
// status from the parent member template that they are specializing.
if (OldFD->isDeleted()) {
@@ -17092,8 +17089,8 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
DeclResult Result = CheckClassTemplate(
S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attrs, TemplateParams,
AS, ModulePrivateLoc,
- /*FriendLoc*/ SourceLocation(), TemplateParameterLists.size() - 1,
- TemplateParameterLists.data(), SkipBody);
+ /*FriendLoc*/ SourceLocation(), TemplateParameterLists.drop_back(),
+ isMemberSpecialization, SkipBody);
return Result.get();
} else {
// The "template<>" header is extraneous.