@@ -2307,8 +2307,12 @@ class ExtractTypeForDeductionGuide
2307
2307
}
2308
2308
};
2309
2309
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 (
2312
2316
Sema &SemaRef, TemplateDecl *OriginalTemplate,
2313
2317
TemplateParameterList *TemplateParams, CXXConstructorDecl *Ctor,
2314
2318
ExplicitSpecifier ES, TypeSourceInfo *TInfo, SourceLocation LocStart,
@@ -2334,16 +2338,21 @@ FunctionTemplateDecl *buildDeductionGuide(
2334
2338
Param->setDeclContext (Guide);
2335
2339
for (auto *TD : MaterializedTypedefs)
2336
2340
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
+ }
2337
2348
2338
2349
auto *GuideTemplate = FunctionTemplateDecl::Create (
2339
2350
SemaRef.Context , DC, Loc, DeductionGuideName, TemplateParams, Guide);
2340
2351
GuideTemplate->setImplicit (IsImplicit);
2341
2352
Guide->setDescribedFunctionTemplate (GuideTemplate);
2342
2353
2343
- if (isa<CXXRecordDecl>(DC)) {
2344
- Guide->setAccess (AS_public);
2354
+ if (isa<CXXRecordDecl>(DC))
2345
2355
GuideTemplate->setAccess (AS_public);
2346
- }
2347
2356
2348
2357
DC->addDecl (GuideTemplate);
2349
2358
return GuideTemplate;
@@ -2990,7 +2999,8 @@ Expr *buildIsDeducibleConstraint(Sema &SemaRef,
2990
2999
ASTContext &Context = SemaRef.Context ;
2991
3000
// Constraint AST nodes must use uninstantiated depth.
2992
3001
if (auto *PrimaryTemplate =
2993
- AliasTemplate->getInstantiatedFromMemberTemplate ()) {
3002
+ AliasTemplate->getInstantiatedFromMemberTemplate ();
3003
+ PrimaryTemplate && TemplateParams.size () > 0 ) {
2994
3004
LocalInstantiationScope Scope (SemaRef);
2995
3005
2996
3006
// Adjust the depth for TemplateParams.
@@ -3254,12 +3264,12 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
3254
3264
FPrimeTemplateParams,
3255
3265
AliasTemplate->getTemplateParameters ()->getRAngleLoc (),
3256
3266
/* RequiresClause=*/ RequiresClause);
3257
- FunctionTemplateDecl *Result = buildDeductionGuide (
3267
+ auto *Result = cast<FunctionTemplateDecl>( buildDeductionGuide (
3258
3268
SemaRef, AliasTemplate, FPrimeTemplateParamList,
3259
3269
GG->getCorrespondingConstructor (), GG->getExplicitSpecifier (),
3260
3270
GG->getTypeSourceInfo (), AliasTemplate->getBeginLoc (),
3261
3271
AliasTemplate->getLocation (), AliasTemplate->getEndLoc (),
3262
- F->isImplicit ());
3272
+ F->isImplicit ())) ;
3263
3273
cast<CXXDeductionGuideDecl>(Result->getTemplatedDecl ())
3264
3274
->setDeductionCandidateKind (GG->getDeductionCandidateKind ());
3265
3275
return Result;
@@ -3290,6 +3300,44 @@ void DeclareImplicitDeductionGuidesForTypeAlias(
3290
3300
Guides.suppressDiagnostics ();
3291
3301
3292
3302
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
+ }
3293
3341
FunctionTemplateDecl *F = dyn_cast<FunctionTemplateDecl>(G);
3294
3342
if (!F)
3295
3343
continue ;
0 commit comments