[Clang] Instantiate Typedefs referenced by type alias deduction guides (#111804)

TypedefNameDecl referenced by a synthesized CTAD guide for type aliases
was not transformed previously, resulting in a substitution failure in
BuildDeductionGuideForTypeAlias() when substituting into the
right-hand-side deduction guide.

This patch fixes it in the way we have been doing since
https://reviews.llvm.org/D80743. We transform all the function
parameters, parenting referenced TypedefNameDecls with the
CXXDeductionGuideDecl. Then we instantiate these declarations in
FindInstantiatedDecl() as we build up the eventual deduction guide,
using the mechanism introduced in D80743

Fixes #111508
This commit is contained in:
Younan Zhang 2024-10-11 10:31:27 +08:00 committed by GitHub
parent 9882b35a3a
commit 0bc02b999a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 3 deletions

View File

@ -70,8 +70,8 @@ public:
ExtractTypeForDeductionGuide(
Sema &SemaRef,
llvm::SmallVectorImpl<TypedefNameDecl *> &MaterializedTypedefs,
ClassTemplateDecl *NestedPattern,
const MultiLevelTemplateArgumentList *OuterInstantiationArgs)
ClassTemplateDecl *NestedPattern = nullptr,
const MultiLevelTemplateArgumentList *OuterInstantiationArgs = nullptr)
: Base(SemaRef), MaterializedTypedefs(MaterializedTypedefs),
NestedPattern(NestedPattern),
OuterInstantiationArgs(OuterInstantiationArgs) {
@ -1228,10 +1228,25 @@ FunctionTemplateDecl *DeclareAggregateDeductionGuideForTypeAlias(
getRHSTemplateDeclAndArgs(SemaRef, AliasTemplate).first;
if (!RHSTemplate)
return nullptr;
llvm::SmallVector<TypedefNameDecl *> TypedefDecls;
llvm::SmallVector<QualType> NewParamTypes;
ExtractTypeForDeductionGuide TypeAliasTransformer(SemaRef, TypedefDecls);
for (QualType P : ParamTypes) {
QualType Type = TypeAliasTransformer.TransformType(P);
if (Type.isNull())
return nullptr;
NewParamTypes.push_back(Type);
}
auto *RHSDeductionGuide = SemaRef.DeclareAggregateDeductionGuideFromInitList(
RHSTemplate, ParamTypes, Loc);
RHSTemplate, NewParamTypes, Loc);
if (!RHSDeductionGuide)
return nullptr;
for (TypedefNameDecl *TD : TypedefDecls)
TD->setDeclContext(RHSDeductionGuide->getTemplatedDecl());
return BuildDeductionGuideForTypeAlias(SemaRef, AliasTemplate,
RHSDeductionGuide, Loc);
}

View File

@ -481,3 +481,16 @@ struct Out {
Out<float>::B out(100); // deduced to Out<float>::A<float>;
static_assert(__is_same(decltype(out), Out<float>::A<float>));
}
namespace GH111508 {
template <typename V> struct S {
using T = V;
T Data;
};
template <typename V> using Alias = S<V>;
Alias A(42);
} // namespace GH111508