[clang] [clang] Implement P2582R1: CTAD from inherited constructors (PR #98788)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 20 22:59:17 PST 2024
================
@@ -931,12 +935,73 @@ 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
+// C++23 [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()),
+ /*Final=*/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)
----------------
antangelo wrote:
I don't believe so, from the comment on `FunctionProtoType` it seems the source location for ellipses is stored in the type itself, and there isn't any mention of them in `FunctionProtoTypeLoc`
https://github.com/llvm/llvm-project/blob/476b208e0115e766605e9f850982996a1d51c287/clang/include/clang/AST/Type.h#L5111-L5112
I have added a C-style variadic test case as well to verify that they work as expected.
https://github.com/llvm/llvm-project/pull/98788
More information about the cfe-commits
mailing list