[clang] [clang] Implement CTAD for type alias template. (PR #77890)
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 23 06:14:38 PST 2024
================
@@ -2612,44 +2671,309 @@ struct ConvertConstructorToDeductionGuideTransform {
SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, NewParam);
return NewParam;
}
+};
- FunctionTemplateDecl *buildDeductionGuide(
- TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor,
- ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart,
- SourceLocation Loc, SourceLocation LocEnd,
- llvm::ArrayRef<TypedefNameDecl *> MaterializedTypedefs = {}) {
- DeclarationNameInfo Name(DeductionGuideName, Loc);
- ArrayRef<ParmVarDecl *> Params =
- TInfo->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams();
+// Find all template parameters of the AliasTemplate that appear in the
+// given DeducedArgs.
+SmallVector<unsigned>
+FindAppearedTemplateParamsInAlias(ArrayRef<TemplateArgument> DeducedArgs,
+ TypeAliasTemplateDecl *AliasTemplate) {
+ struct FindAppearedTemplateParams
+ : public RecursiveASTVisitor<FindAppearedTemplateParams> {
+ llvm::DenseSet<NamedDecl *> TemplateParamsInAlias;
+ llvm::DenseSet<const NamedDecl *> AppearedTemplateParams;
+
+ FindAppearedTemplateParams(ArrayRef<NamedDecl *> TemplateParamsInAlias)
+ : TemplateParamsInAlias(TemplateParamsInAlias.begin(),
+ TemplateParamsInAlias.end()) {}
+
+ bool VisitTemplateTypeParmType(TemplateTypeParmType *TTP) {
+ TTP->getIndex();
+ MarkAppeared(TTP->getDecl());
+ return true;
+ }
+ bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+ MarkAppeared(DRE->getFoundDecl());
+ return true;
+ }
- // Build the implicit deduction guide template.
- auto *Guide =
- CXXDeductionGuideDecl::Create(SemaRef.Context, DC, LocStart, ES, Name,
- TInfo->getType(), TInfo, LocEnd, Ctor);
- Guide->setImplicit();
- Guide->setParams(Params);
+ void MarkAppeared(NamedDecl *ND) {
+ if (TemplateParamsInAlias.contains(ND))
+ AppearedTemplateParams.insert(ND);
+ }
+ };
+ ArrayRef<NamedDecl *> TemplateParamsInAlias =
+ AliasTemplate->getTemplateParameters()->asArray();
+ FindAppearedTemplateParams MarkAppeared(TemplateParamsInAlias);
+ MarkAppeared.TraverseTemplateArguments(DeducedArgs);
- for (auto *Param : Params)
- Param->setDeclContext(Guide);
- for (auto *TD : MaterializedTypedefs)
- TD->setDeclContext(Guide);
+ SmallVector<unsigned> Results;
+ for (unsigned Index = 0; Index < TemplateParamsInAlias.size(); ++Index) {
+ if (MarkAppeared.AppearedTemplateParams.contains(
+ TemplateParamsInAlias[Index]))
+ Results.push_back(Index);
+ }
+ return Results;
+}
- auto *GuideTemplate = FunctionTemplateDecl::Create(
- SemaRef.Context, DC, Loc, DeductionGuideName, TemplateParams, Guide);
- GuideTemplate->setImplicit();
- Guide->setDescribedFunctionTemplate(GuideTemplate);
+bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext* DC) {
+ // Check whether we've already declared deduction guides for this template.
+ // FIXME: Consider storing a flag on the template to indicate this.
+ auto Existing = DC->lookup(Name);
+ for (auto *D : Existing)
+ if (D->isImplicit())
+ return true;
+ return false;
+}
- if (isa<CXXRecordDecl>(DC)) {
- Guide->setAccess(AS_public);
- GuideTemplate->setAccess(AS_public);
+// Build deduction guides for a type alias template.
+void DeclareImplicitDeductionGuidesForTypeAlias(
+ Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate, SourceLocation Loc) {
+ auto &Context = SemaRef.Context;
+ // FIXME: if there is an explicit deduction guide after the first use of the
+ // type alias usage, we will not cover this explicit deduction guide. fix this
+ // case.
+ if (hasDeclaredDeductionGuides(
+ Context.DeclarationNames.getCXXDeductionGuideName(AliasTemplate),
+ AliasTemplate->getDeclContext()))
+ return;
+ // Unrap the sugar ElaboratedType.
----------------
hokein wrote:
Done.
https://github.com/llvm/llvm-project/pull/77890
More information about the cfe-commits
mailing list