aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorMatheus Izvekov <mizvekov@gmail.com>2025-04-01 21:11:56 -0300
committerGitHub <noreply@github.com>2025-04-01 21:11:56 -0300
commitad1ca5f4a2bc09f99fd82e5444f5da37c2985e97 (patch)
tree9d393f3b37d398a8c3bdcc52f68bbeed93773cfe /clang/lib/Sema/SemaTemplateInstantiate.cpp
parent2f25345670081f1ca460ea3f42a0585ef3f1e877 (diff)
downloadllvm-ad1ca5f4a2bc09f99fd82e5444f5da37c2985e97.zip
llvm-ad1ca5f4a2bc09f99fd82e5444f5da37c2985e97.tar.gz
llvm-ad1ca5f4a2bc09f99fd82e5444f5da37c2985e97.tar.bz2
[clang] Concepts: support pack expansions for type constraints (#132626)
This reverts an earlier attempt (adb0d8ddceb143749c519d14b8b31b481071da77 and 50e5411e4247421fd606f0a206682fcdf0303ae3) to support these expansions, which was limited to type arguments and which subverted the purpose of SubstTemplateTypeParmType. This propagates the ArgumentPackSubstitutionIndex along with the AssociatedConstraint, so that the pack expansion works, without needing any new transforms or otherwise any changes to the template instantiation process. This keeps the tests from the reverted commits, and adds a few more showing the new solution also works for NTTPs. Fixes https://github.com/llvm/llvm-project/issues/131798
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp146
1 files changed, 9 insertions, 137 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 00dcadb..9f5ca9d 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1717,24 +1717,6 @@ namespace {
SubstTemplateTypeParmPackTypeLoc TL,
bool SuppressObjCLifetime);
- QualType
- TransformSubstTemplateTypeParmType(TypeLocBuilder &TLB,
- SubstTemplateTypeParmTypeLoc TL) {
- const SubstTemplateTypeParmType *Type = TL.getTypePtr();
- if (Type->getSubstitutionFlag() !=
- SubstTemplateTypeParmTypeFlag::ExpandPacksInPlace)
- return inherited::TransformSubstTemplateTypeParmType(TLB, TL);
-
- assert(Type->getPackIndex());
- TemplateArgument TA = TemplateArgs(
- Type->getReplacedParameter()->getDepth(), Type->getIndex());
- assert(*Type->getPackIndex() + 1 <= TA.pack_size());
- Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
- SemaRef, TA.pack_size() - 1 - *Type->getPackIndex());
-
- return inherited::TransformSubstTemplateTypeParmType(TLB, TL);
- }
-
CXXRecordDecl::LambdaDependencyKind
ComputeLambdaDependency(LambdaScopeInfo *LSI) {
if (auto TypeAlias =
@@ -2894,8 +2876,11 @@ TemplateInstantiator::TransformNestedRequirement(
return nullptr;
llvm::SmallVector<Expr *> Result;
if (!SemaRef.CheckConstraintSatisfaction(
- nullptr, {Req->getConstraintExpr()}, Result, TemplateArgs,
- Req->getConstraintExpr()->getSourceRange(), Satisfaction) &&
+ nullptr,
+ AssociatedConstraint(Req->getConstraintExpr(),
+ SemaRef.ArgumentPackSubstitutionIndex),
+ Result, TemplateArgs, Req->getConstraintExpr()->getSourceRange(),
+ Satisfaction) &&
!Result.empty())
TransConstraint = Result[0];
assert(!Trap.hasErrorOccurred() && "Substitution failures must be handled "
@@ -3169,68 +3154,6 @@ namespace {
} // namespace
-namespace {
-
-struct ExpandPackedTypeConstraints
- : TreeTransform<ExpandPackedTypeConstraints> {
-
- using inherited = TreeTransform<ExpandPackedTypeConstraints>;
-
- const MultiLevelTemplateArgumentList &TemplateArgs;
-
- ExpandPackedTypeConstraints(
- Sema &SemaRef, const MultiLevelTemplateArgumentList &TemplateArgs)
- : inherited(SemaRef), TemplateArgs(TemplateArgs) {}
-
- using inherited::TransformTemplateTypeParmType;
-
- QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
- TemplateTypeParmTypeLoc TL, bool) {
- const TemplateTypeParmType *T = TL.getTypePtr();
- if (!T->isParameterPack()) {
- TemplateTypeParmTypeLoc NewTL =
- TLB.push<TemplateTypeParmTypeLoc>(TL.getType());
- NewTL.setNameLoc(TL.getNameLoc());
- return TL.getType();
- }
-
- assert(SemaRef.ArgumentPackSubstitutionIndex != -1);
-
- TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());
-
- std::optional<unsigned> PackIndex;
- if (Arg.getKind() == TemplateArgument::Pack)
- PackIndex = Arg.pack_size() - 1 - SemaRef.ArgumentPackSubstitutionIndex;
-
- QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
- TL.getType(), T->getDecl(), T->getIndex(), PackIndex,
- SubstTemplateTypeParmTypeFlag::ExpandPacksInPlace);
- SubstTemplateTypeParmTypeLoc NewTL =
- TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
- NewTL.setNameLoc(TL.getNameLoc());
- return Result;
- }
-
- QualType TransformSubstTemplateTypeParmType(TypeLocBuilder &TLB,
- SubstTemplateTypeParmTypeLoc TL) {
- const SubstTemplateTypeParmType *T = TL.getTypePtr();
- if (T->getPackIndex()) {
- SubstTemplateTypeParmTypeLoc TypeLoc =
- TLB.push<SubstTemplateTypeParmTypeLoc>(TL.getType());
- TypeLoc.setNameLoc(TL.getNameLoc());
- return TypeLoc.getType();
- }
- return inherited::TransformSubstTemplateTypeParmType(TLB, TL);
- }
-
- bool SubstTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
- TemplateArgumentListInfo &Out) {
- return inherited::TransformTemplateArguments(Args.begin(), Args.end(), Out);
- }
-};
-
-} // namespace
-
bool Sema::SubstTypeConstraint(
TemplateTypeParmDecl *Inst, const TypeConstraint *TC,
const MultiLevelTemplateArgumentList &TemplateArgs,
@@ -3239,61 +3162,11 @@ bool Sema::SubstTypeConstraint(
TC->getTemplateArgsAsWritten();
if (!EvaluateConstraints) {
- bool ShouldExpandExplicitTemplateArgs =
- TemplArgInfo && ArgumentPackSubstitutionIndex != -1 &&
- llvm::any_of(TemplArgInfo->arguments(), [](auto &Arg) {
- return Arg.getArgument().containsUnexpandedParameterPack();
- });
-
- // We want to transform the packs into Subst* nodes for type constraints
- // inside a pack expansion. For example,
- //
- // template <class... Ts> void foo() {
- // bar([](C<Ts> auto value) {}...);
- // }
- //
- // As we expand Ts in the process of instantiating foo(), and retain
- // the original template depths of Ts until the constraint evaluation, we
- // would otherwise have no chance to expand Ts by the time of evaluating
- // C<auto, Ts>.
- //
- // So we form a Subst* node for Ts along with a proper substitution index
- // here, and substitute the node with a complete MLTAL later in evaluation.
- if (ShouldExpandExplicitTemplateArgs) {
- TemplateArgumentListInfo InstArgs;
- InstArgs.setLAngleLoc(TemplArgInfo->LAngleLoc);
- InstArgs.setRAngleLoc(TemplArgInfo->RAngleLoc);
- if (ExpandPackedTypeConstraints(*this, TemplateArgs)
- .SubstTemplateArguments(TemplArgInfo->arguments(), InstArgs))
- return true;
-
- // The type of the original parameter.
- auto *ConstraintExpr = TC->getImmediatelyDeclaredConstraint();
- QualType ConstrainedType;
-
- if (auto *FE = dyn_cast<CXXFoldExpr>(ConstraintExpr)) {
- assert(FE->getLHS());
- ConstraintExpr = FE->getLHS();
- }
- auto *CSE = cast<ConceptSpecializationExpr>(ConstraintExpr);
- assert(!CSE->getTemplateArguments().empty() &&
- "Empty template arguments?");
- ConstrainedType = CSE->getTemplateArguments()[0].getAsType();
- assert(!ConstrainedType.isNull() &&
- "Failed to extract the original ConstrainedType?");
-
- return AttachTypeConstraint(
- TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(),
- TC->getNamedConcept(),
- /*FoundDecl=*/TC->getConceptReference()->getFoundDecl(), &InstArgs,
- Inst, ConstrainedType,
- Inst->isParameterPack()
- ? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
- ->getEllipsisLoc()
- : SourceLocation());
- }
+ auto Index = TC->getArgumentPackSubstitutionIndex();
+ if (Index == -1)
+ Index = SemaRef.ArgumentPackSubstitutionIndex;
Inst->setTypeConstraint(TC->getConceptReference(),
- TC->getImmediatelyDeclaredConstraint());
+ TC->getImmediatelyDeclaredConstraint(), Index);
return false;
}
@@ -3310,7 +3183,6 @@ bool Sema::SubstTypeConstraint(
TC->getNestedNameSpecifierLoc(), TC->getConceptNameInfo(),
TC->getNamedConcept(),
/*FoundDecl=*/TC->getConceptReference()->getFoundDecl(), &InstArgs, Inst,
- Context.getTypeDeclType(Inst),
Inst->isParameterPack()
? cast<CXXFoldExpr>(TC->getImmediatelyDeclaredConstraint())
->getEllipsisLoc()