@@ -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