[clang] [clang] Implement P2582R1: CTAD from inherited constructors (PR #98788)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 10 16:00:23 PDT 2024
================
@@ -944,12 +950,67 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) {
return {Template, AliasRhsTemplateArgs};
}
+struct InheritedConstructorDeductionInfo {
+ TemplateDecl *DerivedClassTemplate;
+ TypeSourceInfo *CCType;
+};
+
+// Build the type for a deduction guide generated from an inherited constructor
+// [over.match.class.deduct]p1.10:
+// ... the set contains the guides of A with the return type R
+// of each guide replaced with `typename CC<R>::type` ...
+TypeSourceInfo *buildInheritedConstructorDeductionGuideType(
+ Sema &SemaRef, InheritedConstructorDeductionInfo Info,
+ TypeSourceInfo *SourceGuideTSI) {
+ auto &Context = SemaRef.Context;
+ const auto *FPT = SourceGuideTSI->getType()->getAs<FunctionProtoType>();
+ assert(FPT && "Source Guide type should be a FunctionProtoType");
+
+ // This substitution can fail in cases where the source return type
+ // is not dependent and the derived class is not deducible
+ Sema::SFINAETrap Trap(SemaRef);
+
+ MultiLevelTemplateArgumentList Args;
+ Args.addOuterTemplateArguments(Info.DerivedClassTemplate,
+ TemplateArgument(FPT->getReturnType()), false);
+ Args.addOuterRetainedLevels(Info.DerivedClassTemplate->getTemplateDepth());
+ TypeSourceInfo *ReturnTypeTSI = SemaRef.SubstType(
+ Info.CCType, Args, Info.DerivedClassTemplate->getBeginLoc(),
+ DeclarationName());
+ if (!ReturnTypeTSI || Trap.hasErrorOccurred())
+ return nullptr;
+ QualType ReturnType = ReturnTypeTSI->getType();
+
+ TypeLocBuilder TLB;
+ TLB.pushFullCopy(ReturnTypeTSI->getTypeLoc());
+
+ QualType FT = Context.getFunctionType(ReturnType, FPT->getParamTypes(),
+ FPT->getExtProtoInfo());
+ FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(FT);
+ const auto &TL = SourceGuideTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
+ NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
+ NewTL.setLParenLoc(TL.getLParenLoc());
+ NewTL.setRParenLoc(TL.getRParenLoc());
+ NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
+ NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
+ for (unsigned I = 0, E = NewTL.getNumParams(); I != E; ++I)
+ NewTL.setParam(I, TL.getParam(I));
+
+ TypeSourceInfo *TSI = TLB.getTypeSourceInfo(Context, FT);
+ return TSI;
+}
+
// Build deduction guides for a type alias template from the given underlying
// deduction guide F.
-FunctionTemplateDecl *
-BuildDeductionGuideForTypeAlias(Sema &SemaRef,
- TypeAliasTemplateDecl *AliasTemplate,
- FunctionTemplateDecl *F, SourceLocation Loc) {
+// If F is synthesized from a base class (as an inherited constructor),
+// then the return type will be transformed using DerivedClassMapperType.
+// The resulting deduction guide is added to the DeducingTemplate argument,
+// defaulting to AliasTemplate.
+FunctionTemplateDecl *BuildDeductionGuideForTypeAlias(
+ Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate,
+ FunctionTemplateDecl *F, SourceLocation Loc,
+ std::optional<InheritedConstructorDeductionInfo> FromInheritedCtor =
----------------
antangelo wrote:
Done
https://github.com/llvm/llvm-project/pull/98788
More information about the cfe-commits
mailing list