diff options
author | Matheus Izvekov <mizvekov@gmail.com> | 2025-09-24 17:18:41 -0300 |
---|---|---|
committer | Matheus Izvekov <mizvekov@gmail.com> | 2025-09-26 16:18:42 -0300 |
commit | 1160542a693e22cc81c719e371d1b6282ecc3800 (patch) | |
tree | 1c23ff6c8b9bc54926911560b84450d937e51047 /clang/lib/Sema/SemaTemplate.cpp | |
parent | 21fe7eea5c0f7dbfe8b08251a594c23ea2e8980d (diff) | |
download | llvm-users/mizvekov/fix-substnttp-transform.zip llvm-users/mizvekov/fix-substnttp-transform.tar.gz llvm-users/mizvekov/fix-substnttp-transform.tar.bz2 |
[clang] fix transformation of subst constant template parameter nodesusers/mizvekov/fix-substnttp-transform
This simplifies those transforms a lot, removing a bunch of workarounds
which were introducing problems.
The transforms become independent of the template instantiator, so
they are moved to TreeTransform instead.
Fixes #131342
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 91e4dc8..3ebbb30 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -775,6 +775,40 @@ Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS, TemplateArgs); } +ExprResult Sema::BuildSubstNonTypeTemplateParmExpr( + Decl *AssociatedDecl, const NonTypeTemplateParmDecl *NTTP, + SourceLocation Loc, TemplateArgument Arg, UnsignedOrNone PackIndex, + bool Final) { + // The template argument itself might be an expression, in which case we just + // return that expression. This happens when substituting into an alias + // template. + Expr *Replacement; + bool refParam = true; + if (Arg.getKind() == TemplateArgument::Expression) { + Replacement = Arg.getAsExpr(); + refParam = Replacement->isLValue(); + if (refParam && Replacement->getType()->isRecordType()) { + QualType ParamType = + NTTP->isExpandedParameterPack() + ? NTTP->getExpansionType(*SemaRef.ArgPackSubstIndex) + : NTTP->getType(); + if (const auto *PET = dyn_cast<PackExpansionType>(ParamType)) + ParamType = PET->getPattern(); + refParam = ParamType->isReferenceType(); + } + } else { + ExprResult result = + SemaRef.BuildExpressionFromNonTypeTemplateArgument(Arg, Loc); + if (result.isInvalid()) + return ExprError(); + Replacement = result.get(); + refParam = Arg.getNonTypeTemplateArgumentType()->isReferenceType(); + } + return new (SemaRef.Context) SubstNonTypeTemplateParmExpr( + Replacement->getType(), Replacement->getValueKind(), Loc, Replacement, + AssociatedDecl, NTTP->getIndex(), PackIndex, refParam, Final); +} + bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation, NamedDecl *Instantiation, bool InstantiatedFromMember, |