Skip to content

[Clang][Sema] Use the correct injected template arguments for partial specializations when collecting multi-level template argument lists #112381

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion clang/include/clang/AST/DeclTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -2085,7 +2085,11 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
class ClassTemplatePartialSpecializationDecl
: public ClassTemplateSpecializationDecl {
/// The list of template parameters
TemplateParameterList* TemplateParams = nullptr;
TemplateParameterList *TemplateParams = nullptr;

/// The set of "injected" template arguments used within this
/// partial specialization.
TemplateArgument *InjectedArgs = nullptr;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need serialization?

Copy link
Contributor

@mizvekov mizvekov Oct 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just for caching the injected arguments. If we don't serialize these, they will be just rebuilt anyway.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, like @mizvekov said we don't serialize injected template arguments


/// The class template partial specialization from which this
/// class template partial specialization was instantiated.
Expand Down Expand Up @@ -2132,6 +2136,10 @@ class ClassTemplatePartialSpecializationDecl
return TemplateParams;
}

/// Retrieve the template arguments list of the template parameter list
/// of this template.
ArrayRef<TemplateArgument> getInjectedTemplateArgs();

/// \brief All associated constraints of this partial specialization,
/// including the requires clause and any constraints derived from
/// constrained-parameters.
Expand Down Expand Up @@ -2856,6 +2864,10 @@ class VarTemplatePartialSpecializationDecl
/// The list of template parameters
TemplateParameterList *TemplateParams = nullptr;

/// The set of "injected" template arguments used within this
/// partial specialization.
TemplateArgument *InjectedArgs = nullptr;

/// The variable template partial specialization from which this
/// variable template partial specialization was instantiated.
///
Expand Down Expand Up @@ -2902,6 +2914,10 @@ class VarTemplatePartialSpecializationDecl
return TemplateParams;
}

/// Retrieve the template arguments list of the template parameter list
/// of this template.
ArrayRef<TemplateArgument> getInjectedTemplateArgs();

/// \brief All associated constraints of this partial specialization,
/// including the requires clause and any constraints derived from
/// constrained-parameters.
Expand Down
28 changes: 28 additions & 0 deletions clang/lib/AST/DeclTemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,20 @@ SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {
return Range;
}

ArrayRef<TemplateArgument>
ClassTemplatePartialSpecializationDecl::getInjectedTemplateArgs() {
TemplateParameterList *Params = getTemplateParameters();
auto *First = cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
if (!First->InjectedArgs) {
auto &Context = getASTContext();
SmallVector<TemplateArgument, 16> TemplateArgs;
Context.getInjectedTemplateArgs(Params, TemplateArgs);
First->InjectedArgs = new (Context) TemplateArgument[TemplateArgs.size()];
std::copy(TemplateArgs.begin(), TemplateArgs.end(), First->InjectedArgs);
}
return llvm::ArrayRef(First->InjectedArgs, Params->size());
}

//===----------------------------------------------------------------------===//
// FriendTemplateDecl Implementation
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1535,6 +1549,20 @@ SourceRange VarTemplatePartialSpecializationDecl::getSourceRange() const {
return Range;
}

ArrayRef<TemplateArgument>
VarTemplatePartialSpecializationDecl::getInjectedTemplateArgs() {
TemplateParameterList *Params = getTemplateParameters();
auto *First = cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
if (!First->InjectedArgs) {
auto &Context = getASTContext();
SmallVector<TemplateArgument, 16> TemplateArgs;
Context.getInjectedTemplateArgs(Params, TemplateArgs);
First->InjectedArgs = new (Context) TemplateArgument[TemplateArgs.size()];
std::copy(TemplateArgs.begin(), TemplateArgs.end(), First->InjectedArgs);
}
return llvm::ArrayRef(First->InjectedArgs, Params->size());
}

static TemplateParameterList *
createMakeIntegerSeqParameterList(const ASTContext &C, DeclContext *DC) {
// typename T
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaTemplateInstantiate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ struct TemplateInstantiationArgumentCollecter
if (Innermost)
AddInnermostTemplateArguments(VTPSD);
else if (ForConstraintInstantiation)
AddOuterTemplateArguments(VTPSD, VTPSD->getTemplateArgs().asArray(),
AddOuterTemplateArguments(VTPSD, VTPSD->getInjectedTemplateArgs(),
/*Final=*/false);

if (VTPSD->isMemberSpecialization())
Expand Down Expand Up @@ -274,7 +274,7 @@ struct TemplateInstantiationArgumentCollecter
if (Innermost)
AddInnermostTemplateArguments(CTPSD);
else if (ForConstraintInstantiation)
AddOuterTemplateArguments(CTPSD, CTPSD->getTemplateArgs().asArray(),
AddOuterTemplateArguments(CTPSD, CTPSD->getInjectedTemplateArgs(),
/*Final=*/false);

if (CTPSD->isMemberSpecialization())
Expand Down
Loading
Loading