@@ -507,10 +507,70 @@ static TemplateDeductionResult DeduceNonTypeTemplateArgument(
507507 S, TemplateParams, NTTP, DeducedTemplateArgument (New), T, Info, Deduced);
508508}
509509
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+
510569static TemplateDeductionResult
511570DeduceTemplateArguments (Sema &S, TemplateParameterList *TemplateParams,
512571 TemplateName Param, TemplateName Arg,
513572 TemplateDeductionInfo &Info,
573+ ArrayRef<TemplateArgument> DefaultArguments,
514574 SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
515575 TemplateDecl *ParamDecl = Param.getAsTemplateDecl ();
516576 if (!ParamDecl) {
@@ -519,13 +579,45 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
519579 return TemplateDeductionResult::Success;
520580 }
521581
522- if (TemplateTemplateParmDecl *TempParam
523- = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
582+ if (auto *TempParam = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
524583 // If we're not deducing at this depth, there's nothing to deduce.
525584 if (TempParam->getDepth () != Info.getDeducedDepth ())
526585 return TemplateDeductionResult::Success;
527586
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+
529621 DeducedTemplateArgument Result = checkDeducedTemplateArguments (S.Context ,
530622 Deduced[TempParam->getIndex ()],
531623 NewDeduced);
@@ -604,7 +696,8 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
604696
605697 // Perform template argument deduction for the template name.
606698 if (auto Result =
607- DeduceTemplateArguments (S, TemplateParams, TNP, TNA, Info, Deduced);
699+ DeduceTemplateArguments (S, TemplateParams, TNP, TNA, Info,
700+ SA->template_arguments (), Deduced);
608701 Result != TemplateDeductionResult::Success)
609702 return Result;
610703 // Perform template argument deduction on each template
@@ -630,7 +723,8 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
630723 // Perform template argument deduction for the template name.
631724 if (auto Result = DeduceTemplateArguments (
632725 S, TemplateParams, TP->getTemplateName (),
633- TemplateName (SA->getSpecializedTemplate ()), Info, Deduced);
726+ TemplateName (SA->getSpecializedTemplate ()), Info,
727+ SA->getTemplateArgs ().asArray (), Deduced);
634728 Result != TemplateDeductionResult::Success)
635729 return Result;
636730
@@ -2323,7 +2417,8 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
23232417 case TemplateArgument::Template:
23242418 if (A.getKind () == TemplateArgument::Template)
23252419 return DeduceTemplateArguments (S, TemplateParams, P.getAsTemplate (),
2326- A.getAsTemplate (), Info, Deduced);
2420+ A.getAsTemplate (), Info,
2421+ /* DefaultArguments=*/ {}, Deduced);
23272422 Info.FirstArg = P;
23282423 Info.SecondArg = A;
23292424 return TemplateDeductionResult::NonDeducedMismatch;
0 commit comments