@@ -507,10 +507,70 @@ static TemplateDeductionResult DeduceNonTypeTemplateArgument(
507
507
S, TemplateParams, NTTP, DeducedTemplateArgument (New), T, Info, Deduced);
508
508
}
509
509
510
+ // / Create a shallow copy of a given template parameter declaration, with
511
+ // / empty source locations and using the given TemplateArgument as it's
512
+ // / default argument.
513
+ // /
514
+ // / \returns The new template parameter declaration.
515
+ static NamedDecl *getTemplateParameterWithDefault (Sema &S, NamedDecl *A,
516
+ TemplateArgument Default) {
517
+ switch (A->getKind ()) {
518
+ case Decl::TemplateTypeParm: {
519
+ auto *T = cast<TemplateTypeParmDecl>(A);
520
+ // FIXME: A TemplateTypeParmDecl's DefaultArgument can't hold a full
521
+ // TemplateArgument, so there is currently no way to specify a pack as a
522
+ // default argument for these.
523
+ if (T->isParameterPack ())
524
+ return A;
525
+ auto *R = TemplateTypeParmDecl::Create (
526
+ S.Context , A->getDeclContext (), SourceLocation (), SourceLocation (),
527
+ T->getDepth (), T->getIndex (), T->getIdentifier (),
528
+ T->wasDeclaredWithTypename (), /* ParameterPack=*/ false ,
529
+ T->hasTypeConstraint ());
530
+ R->setDefaultArgument (
531
+ S.Context .getTrivialTypeSourceInfo (Default.getAsType ()));
532
+ if (R->hasTypeConstraint ()) {
533
+ auto *C = R->getTypeConstraint ();
534
+ R->setTypeConstraint (C->getConceptReference (),
535
+ C->getImmediatelyDeclaredConstraint ());
536
+ }
537
+ return R;
538
+ }
539
+ case Decl::NonTypeTemplateParm: {
540
+ auto *T = cast<NonTypeTemplateParmDecl>(A);
541
+ // FIXME: Ditto, as above for TemplateTypeParm case.
542
+ if (T->isParameterPack ())
543
+ return A;
544
+ auto *R = NonTypeTemplateParmDecl::Create (
545
+ S.Context , A->getDeclContext (), SourceLocation (), SourceLocation (),
546
+ T->getDepth (), T->getIndex (), T->getIdentifier (), T->getType (),
547
+ /* ParameterPack=*/ false , T->getTypeSourceInfo ());
548
+ R->setDefaultArgument (Default.getAsExpr ());
549
+ if (auto *PTC = T->getPlaceholderTypeConstraint ())
550
+ R->setPlaceholderTypeConstraint (PTC);
551
+ return R;
552
+ }
553
+ case Decl::TemplateTemplateParm: {
554
+ auto *T = cast<TemplateTemplateParmDecl>(A);
555
+ auto *R = TemplateTemplateParmDecl::Create (
556
+ S.Context , A->getDeclContext (), SourceLocation (), T->getDepth (),
557
+ T->getIndex (), T->isParameterPack (), T->getIdentifier (),
558
+ T->wasDeclaredWithTypename (), T->getTemplateParameters ());
559
+ R->setDefaultArgument (
560
+ S.Context ,
561
+ S.getTrivialTemplateArgumentLoc (Default, QualType (), SourceLocation ()));
562
+ return R;
563
+ }
564
+ default :
565
+ llvm_unreachable (" Unexpected Decl Kind" );
566
+ }
567
+ }
568
+
510
569
static TemplateDeductionResult
511
570
DeduceTemplateArguments (Sema &S, TemplateParameterList *TemplateParams,
512
571
TemplateName Param, TemplateName Arg,
513
572
TemplateDeductionInfo &Info,
573
+ ArrayRef<TemplateArgument> DefaultArguments,
514
574
SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
515
575
TemplateDecl *ParamDecl = Param.getAsTemplateDecl ();
516
576
if (!ParamDecl) {
@@ -519,13 +579,45 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
519
579
return TemplateDeductionResult::Success;
520
580
}
521
581
522
- if (TemplateTemplateParmDecl *TempParam
523
- = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
582
+ if (auto *TempParam = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
524
583
// If we're not deducing at this depth, there's nothing to deduce.
525
584
if (TempParam->getDepth () != Info.getDeducedDepth ())
526
585
return TemplateDeductionResult::Success;
527
586
528
- DeducedTemplateArgument NewDeduced (S.Context .getCanonicalTemplateName (Arg));
587
+ auto NewDeduced = DeducedTemplateArgument (Arg);
588
+ // Provisional resolution for CWG2398: If Arg is also a template template
589
+ // param, and it names a template specialization, then we deduce a
590
+ // synthesized template template parameter based on A, but using the TS's
591
+ // arguments as defaults.
592
+ if (auto *TempArg = dyn_cast_or_null<TemplateTemplateParmDecl>(
593
+ Arg.getAsTemplateDecl ())) {
594
+ assert (Arg.getKind () == TemplateName::Template);
595
+ assert (!TempArg->isExpandedParameterPack ());
596
+
597
+ TemplateParameterList *As = TempArg->getTemplateParameters ();
598
+ if (DefaultArguments.size () != 0 ) {
599
+ assert (DefaultArguments.size () <= As->size ());
600
+ SmallVector<NamedDecl *, 4 > Params (As->size ());
601
+ for (unsigned I = 0 ; I < DefaultArguments.size (); ++I)
602
+ Params[I] = getTemplateParameterWithDefault (S, As->getParam (I),
603
+ DefaultArguments[I]);
604
+ for (unsigned I = DefaultArguments.size (); I < As->size (); ++I)
605
+ Params[I] = As->getParam (I);
606
+ // FIXME: We could unique these, and also the parameters, but we don't
607
+ // expect programs to contain a large enough amount of these deductions
608
+ // for that to be worthwhile.
609
+ auto *TPL = TemplateParameterList::Create (
610
+ S.Context , SourceLocation (), SourceLocation (), Params,
611
+ SourceLocation (), As->getRequiresClause ());
612
+ NewDeduced = DeducedTemplateArgument (
613
+ TemplateName (TemplateTemplateParmDecl::Create (
614
+ S.Context , TempArg->getDeclContext (), SourceLocation (),
615
+ TempArg->getDepth (), TempArg->getPosition (),
616
+ TempArg->isParameterPack (), TempArg->getIdentifier (),
617
+ TempArg->wasDeclaredWithTypename (), TPL)));
618
+ }
619
+ }
620
+
529
621
DeducedTemplateArgument Result = checkDeducedTemplateArguments (S.Context ,
530
622
Deduced[TempParam->getIndex ()],
531
623
NewDeduced);
@@ -604,7 +696,8 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
604
696
605
697
// Perform template argument deduction for the template name.
606
698
if (auto Result =
607
- DeduceTemplateArguments (S, TemplateParams, TNP, TNA, Info, Deduced);
699
+ DeduceTemplateArguments (S, TemplateParams, TNP, TNA, Info,
700
+ SA->template_arguments (), Deduced);
608
701
Result != TemplateDeductionResult::Success)
609
702
return Result;
610
703
// Perform template argument deduction on each template
@@ -630,7 +723,8 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
630
723
// Perform template argument deduction for the template name.
631
724
if (auto Result = DeduceTemplateArguments (
632
725
S, TemplateParams, TP->getTemplateName (),
633
- TemplateName (SA->getSpecializedTemplate ()), Info, Deduced);
726
+ TemplateName (SA->getSpecializedTemplate ()), Info,
727
+ SA->getTemplateArgs ().asArray (), Deduced);
634
728
Result != TemplateDeductionResult::Success)
635
729
return Result;
636
730
@@ -2323,7 +2417,8 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
2323
2417
case TemplateArgument::Template:
2324
2418
if (A.getKind () == TemplateArgument::Template)
2325
2419
return DeduceTemplateArguments (S, TemplateParams, P.getAsTemplate (),
2326
- A.getAsTemplate (), Info, Deduced);
2420
+ A.getAsTemplate (), Info,
2421
+ /* DefaultArguments=*/ {}, Deduced);
2327
2422
Info.FirstArg = P;
2328
2423
Info.SecondArg = A;
2329
2424
return TemplateDeductionResult::NonDeducedMismatch;
0 commit comments