[clang] [clang] Implement P2582R1: CTAD from inherited constructors (PR #98788)
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 30 05:01:47 PDT 2024
================
@@ -944,12 +950,72 @@ getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) {
return {Template, AliasRhsTemplateArgs};
}
+struct InheritedConstructorDeductionInfo {
+ // Class template for which we are declaring deduction guides
+ // This is `C` in the standard wording
+ TemplateDecl *DerivedClassTemplate;
+
+ // `template<typename> CC` in the standard wording
+ // This is the type of template that is substituted in the deduction guide
+ // return type `CC<R>`
+ 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, const 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.
----------------
hokein wrote:
the comment (`DerivedClassMapperType`) seems outdated as the code has evolved. Can you update it?
https://github.com/llvm/llvm-project/pull/98788
More information about the cfe-commits
mailing list