@@ -507,10 +507,62 @@ static TemplateDeductionResult DeduceNonTypeTemplateArgument(
507507      S, TemplateParams, NTTP, DeducedTemplateArgument (New), T, Info, Deduced);
508508}
509509
510+ static  NamedDecl *DeduceTemplateArguments (Sema &S, NamedDecl *A,
511+                                           TemplateArgument Default) {
512+   switch  (A->getKind ()) {
513+   case  Decl::TemplateTypeParm: {
514+     auto  *T = cast<TemplateTypeParmDecl>(A);
515+     //  FIXME: DefaultArgument can't represent a pack.
516+     if  (T->isParameterPack ())
517+       return  A;
518+     auto  *R = TemplateTypeParmDecl::Create (
519+         S.Context , A->getDeclContext (), SourceLocation (), SourceLocation (),
520+         T->getDepth (), T->getIndex (), T->getIdentifier (),
521+         T->wasDeclaredWithTypename (), /* ParameterPack=*/ false ,
522+         T->hasTypeConstraint ());
523+     R->setDefaultArgument (
524+         S.Context .getTrivialTypeSourceInfo (Default.getAsType ()));
525+     if  (R->hasTypeConstraint ()) {
526+       auto  *C = R->getTypeConstraint ();
527+       R->setTypeConstraint (C->getConceptReference (),
528+                            C->getImmediatelyDeclaredConstraint ());
529+     }
530+     return  R;
531+   }
532+   case  Decl::NonTypeTemplateParm: {
533+     auto  *T = cast<NonTypeTemplateParmDecl>(A);
534+     //  FIXME: DefaultArgument can't represent a pack.
535+     if  (T->isParameterPack ())
536+       return  A;
537+     auto  *R = NonTypeTemplateParmDecl::Create (
538+         S.Context , A->getDeclContext (), SourceLocation (), SourceLocation (),
539+         T->getDepth (), T->getIndex (), T->getIdentifier (), T->getType (),
540+         /* ParameterPack=*/ false , T->getTypeSourceInfo ());
541+     R->setDefaultArgument (Default.getAsExpr ());
542+     if  (auto  *PTC = T->getPlaceholderTypeConstraint ())
543+       R->setPlaceholderTypeConstraint (PTC);
544+     return  R;
545+   }
546+   case  Decl::TemplateTemplateParm: {
547+     auto  *T = cast<TemplateTemplateParmDecl>(A);
548+     auto  *R = TemplateTemplateParmDecl::Create (
549+         S.Context , A->getDeclContext (), SourceLocation (), T->getDepth (),
550+         T->getIndex (), T->isParameterPack (), T->getIdentifier (),
551+         T->wasDeclaredWithTypename (), T->getTemplateParameters ());
552+     R->setDefaultArgument (
553+         S.Context , TemplateArgumentLoc (Default, TemplateArgumentLocInfo ()));
554+     return  R;
555+   }
556+   default :
557+     llvm_unreachable (" Unexpected Decl Kind"  );
558+   }
559+ }
560+ 
510561static  TemplateDeductionResult
511562DeduceTemplateArguments (Sema &S, TemplateParameterList *TemplateParams,
512563                        TemplateName Param, TemplateName Arg,
513564                        TemplateDeductionInfo &Info,
565+                         ArrayRef<TemplateArgument> DefaultArguments,
514566                        SmallVectorImpl<DeducedTemplateArgument> &Deduced) {
515567  TemplateDecl *ParamDecl = Param.getAsTemplateDecl ();
516568  if  (!ParamDecl) {
@@ -519,13 +571,45 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
519571    return  TemplateDeductionResult::Success;
520572  }
521573
522-   if  (TemplateTemplateParmDecl *TempParam
523-         = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
574+   if  (auto  *TempParam = dyn_cast<TemplateTemplateParmDecl>(ParamDecl)) {
524575    //  If we're not deducing at this depth, there's nothing to deduce.
525576    if  (TempParam->getDepth () != Info.getDeducedDepth ())
526577      return  TemplateDeductionResult::Success;
527578
528-     DeducedTemplateArgument NewDeduced (S.Context .getCanonicalTemplateName (Arg));
579+     auto  NewDeduced = DeducedTemplateArgument (Arg);
580+     //  Provisional resolution for CWG2398: If Arg is also a template template
581+     //  param, and it names a template specialization, then we deduce a
582+     //  synthesized template template parameter based on A, but using the TS's
583+     //  arguments as defaults.
584+     if  (auto  *TempArg = dyn_cast_or_null<TemplateTemplateParmDecl>(
585+             Arg.getAsTemplateDecl ())) {
586+       assert (Arg.getKind () == TemplateName::Template);
587+       assert (!TempArg->isExpandedParameterPack ());
588+ 
589+       TemplateParameterList *As = TempArg->getTemplateParameters ();
590+       if  (DefaultArguments.size () != 0 ) {
591+         assert (DefaultArguments.size () <= As->size ());
592+         SmallVector<NamedDecl *, 4 > Params (As->size ());
593+         for  (unsigned  I = 0 ; I < DefaultArguments.size (); ++I)
594+           Params[I] =
595+               DeduceTemplateArguments (S, As->getParam (I), DefaultArguments[I]);
596+         for  (unsigned  I = DefaultArguments.size (); I < As->size (); ++I)
597+           Params[I] = As->getParam (I);
598+         //  FIXME: We could unique these, and also the parameters, but we don't
599+         //  expect programs to contain a large enough amount of these deductions
600+         //  for that to be worthwhile.
601+         auto  *TPL = TemplateParameterList::Create (
602+             S.Context , SourceLocation (), SourceLocation (), Params,
603+             SourceLocation (), As->getRequiresClause ());
604+         NewDeduced = DeducedTemplateArgument (
605+             TemplateName (TemplateTemplateParmDecl::Create (
606+                 S.Context , TempArg->getDeclContext (), SourceLocation (),
607+                 TempArg->getDepth (), TempArg->getPosition (),
608+                 TempArg->isParameterPack (), TempArg->getIdentifier (),
609+                 TempArg->wasDeclaredWithTypename (), TPL)));
610+       }
611+     }
612+ 
529613    DeducedTemplateArgument Result = checkDeducedTemplateArguments (S.Context ,
530614                                                 Deduced[TempParam->getIndex ()],
531615                                                                   NewDeduced);
@@ -604,7 +688,8 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
604688
605689    //  Perform template argument deduction for the template name.
606690    if  (auto  Result =
607-             DeduceTemplateArguments (S, TemplateParams, TNP, TNA, Info, Deduced);
691+             DeduceTemplateArguments (S, TemplateParams, TNP, TNA, Info,
692+                                     SA->template_arguments (), Deduced);
608693        Result != TemplateDeductionResult::Success)
609694      return  Result;
610695    //  Perform template argument deduction on each template
@@ -630,7 +715,8 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
630715  //  Perform template argument deduction for the template name.
631716  if  (auto  Result = DeduceTemplateArguments (
632717          S, TemplateParams, TP->getTemplateName (),
633-           TemplateName (SA->getSpecializedTemplate ()), Info, Deduced);
718+           TemplateName (SA->getSpecializedTemplate ()), Info,
719+           SA->getTemplateArgs ().asArray (), Deduced);
634720      Result != TemplateDeductionResult::Success)
635721    return  Result;
636722
@@ -2320,7 +2406,8 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
23202406  case  TemplateArgument::Template:
23212407    if  (A.getKind () == TemplateArgument::Template)
23222408      return  DeduceTemplateArguments (S, TemplateParams, P.getAsTemplate (),
2323-                                      A.getAsTemplate (), Info, Deduced);
2409+                                      A.getAsTemplate (), Info,
2410+                                      /* DefaultArguments=*/  {}, Deduced);
23242411    Info.FirstArg  = P;
23252412    Info.SecondArg  = A;
23262413    return  TemplateDeductionResult::NonDeducedMismatch;
0 commit comments