@@ -2307,8 +2307,12 @@ class ExtractTypeForDeductionGuide
23072307 }
23082308};
23092309
2310- // Build a deduction guide with the specified parameter types.
2311- FunctionTemplateDecl *buildDeductionGuide (
2310+ // Build a deduction guide using the provided information.
2311+ //
2312+ // A deduction guide can be either a template or a non-template function
2313+ // declaration. If \p TemplateParams is null, a non-template function
2314+ // declaration will be created.
2315+ NamedDecl *buildDeductionGuide (
23122316 Sema &SemaRef, TemplateDecl *OriginalTemplate,
23132317 TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor,
23142318 ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart,
@@ -2334,16 +2338,21 @@ FunctionTemplateDecl *buildDeductionGuide(
23342338 Param->setDeclContext (Guide);
23352339 for (auto *TD : MaterializedTypedefs)
23362340 TD->setDeclContext (Guide);
2341+ if (isa<CXXRecordDecl>(DC))
2342+ Guide->setAccess (AS_public);
2343+
2344+ if (!TemplateParams) {
2345+ DC->addDecl (Guide);
2346+ return Guide;
2347+ }
23372348
23382349 auto *GuideTemplate = FunctionTemplateDecl::Create (
23392350 SemaRef.Context , DC, Loc, DeductionGuideName, TemplateParams, Guide);
23402351 GuideTemplate->setImplicit (IsImplicit);
23412352 Guide->setDescribedFunctionTemplate (GuideTemplate);
23422353
2343- if (isa<CXXRecordDecl>(DC)) {
2344- Guide->setAccess (AS_public);
2354+ if (isa<CXXRecordDecl>(DC))
23452355 GuideTemplate->setAccess (AS_public);
2346- }
23472356
23482357 DC->addDecl (GuideTemplate);
23492358 return GuideTemplate;
@@ -2990,7 +2999,8 @@ Expr *buildIsDeducibleConstraint(Sema &SemaRef,
29902999 ASTContext &Context = SemaRef.Context ;
29913000 // Constraint AST nodes must use uninstantiated depth.
29923001 if (auto *PrimaryTemplate =
2993- AliasTemplate->getInstantiatedFromMemberTemplate ()) {
3002+ AliasTemplate->getInstantiatedFromMemberTemplate ();
3003+ PrimaryTemplate && TemplateParams.size () > 0 ) {
29943004 LocalInstantiationScope Scope (SemaRef);
29953005
29963006 // Adjust the depth for TemplateParams.
@@ -3254,12 +3264,12 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
32543264 FPrimeTemplateParams,
32553265 AliasTemplate->getTemplateParameters ()->getRAngleLoc (),
32563266 /* RequiresClause=*/ RequiresClause);
3257- FunctionTemplateDecl *Result = buildDeductionGuide (
3267+ auto *Result = cast<FunctionTemplateDecl>( buildDeductionGuide (
32583268 SemaRef, AliasTemplate, FPrimeTemplateParamList,
32593269 GG->getCorrespondingConstructor (), GG->getExplicitSpecifier (),
32603270 GG->getTypeSourceInfo (), AliasTemplate->getBeginLoc (),
32613271 AliasTemplate->getLocation (), AliasTemplate->getEndLoc (),
3262- F->isImplicit ());
3272+ F->isImplicit ())) ;
32633273 cast<CXXDeductionGuideDecl>(Result->getTemplatedDecl ())
32643274 ->setDeductionCandidateKind (GG->getDeductionCandidateKind ());
32653275 return Result;
@@ -3290,6 +3300,44 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
32903300 Guides.suppressDiagnostics ();
32913301
32923302 for (auto *G : Guides) {
3303+ if (auto *DG = dyn_cast<CXXDeductionGuideDecl>(G)) {
3304+ // The deduction guide is a non-template function decl, we just clone it.
3305+ auto *FunctionType =
3306+ SemaRef.Context .getTrivialTypeSourceInfo (DG->getType ());
3307+ FunctionProtoTypeLoc FPTL =
3308+ FunctionType->getTypeLoc ().castAs <FunctionProtoTypeLoc>();
3309+
3310+ // Clone the parameters.
3311+ for (unsigned I = 0 , N = DG->getNumParams (); I != N; ++I) {
3312+ const auto *P = DG->getParamDecl (I);
3313+ auto *TSI = SemaRef.Context .getTrivialTypeSourceInfo (P->getType ());
3314+ ParmVarDecl *NewParam = ParmVarDecl::Create (
3315+ SemaRef.Context , G->getDeclContext (),
3316+ DG->getParamDecl (I)->getBeginLoc (), P->getLocation (), nullptr ,
3317+ TSI->getType (), TSI, SC_None, nullptr );
3318+ NewParam->setScopeInfo (0 , I);
3319+ FPTL.setParam (I, NewParam);
3320+ }
3321+ auto *Transformed = cast<FunctionDecl>(buildDeductionGuide (
3322+ SemaRef, AliasTemplate, /* TemplateParams=*/ nullptr ,
3323+ /* Constructor=*/ nullptr , DG->getExplicitSpecifier (), FunctionType,
3324+ AliasTemplate->getBeginLoc (), AliasTemplate->getLocation (),
3325+ AliasTemplate->getEndLoc (), DG->isImplicit ()));
3326+
3327+ // FIXME: Here the synthesized deduction guide is not a templated
3328+ // function. Per [dcl.decl]p4, the requires-clause shall be present only
3329+ // if the declarator declares a templated function, a bug in standard?
3330+ auto *Constraint = buildIsDeducibleConstraint (
3331+ SemaRef, AliasTemplate, Transformed->getReturnType (), {});
3332+ if (auto *RC = DG->getTrailingRequiresClause ()) {
3333+ auto Conjunction =
3334+ SemaRef.BuildBinOp (SemaRef.getCurScope (), SourceLocation{},
3335+ BinaryOperatorKind::BO_LAnd, RC, Constraint);
3336+ if (!Conjunction.isInvalid ())
3337+ Constraint = Conjunction.getAs <Expr>();
3338+ }
3339+ Transformed->setTrailingRequiresClause (Constraint);
3340+ }
32933341 FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(G);
32943342 if (!F)
32953343 continue ;
0 commit comments