3939#include " clang/Sema/Overload.h"
4040#include " clang/Sema/Ownership.h"
4141#include " clang/Sema/Scope.h"
42+ #include " clang/Sema/SemaInternal.h"
4243#include " clang/Sema/Template.h"
4344#include " clang/Sema/TemplateDeduction.h"
4445#include " llvm/ADT/ArrayRef.h"
@@ -241,11 +242,10 @@ NamedDecl *buildDeductionGuide(
241242}
242243
243244// Transform a given template type parameter `TTP`.
244- TemplateTypeParmDecl *
245- transformTemplateTypeParam (Sema &SemaRef, DeclContext *DC,
246- TemplateTypeParmDecl *TTP,
247- MultiLevelTemplateArgumentList &Args,
248- unsigned NewDepth, unsigned NewIndex) {
245+ TemplateTypeParmDecl *transformTemplateTypeParam (
246+ Sema &SemaRef, DeclContext *DC, TemplateTypeParmDecl *TTP,
247+ MultiLevelTemplateArgumentList &Args, unsigned NewDepth, unsigned NewIndex,
248+ bool EvaluateConstraint) {
249249 // TemplateTypeParmDecl's index cannot be changed after creation, so
250250 // substitute it directly.
251251 auto *NewTTP = TemplateTypeParmDecl::Create (
@@ -257,7 +257,7 @@ transformTemplateTypeParam(Sema &SemaRef, DeclContext *DC,
257257 : std::nullopt );
258258 if (const auto *TC = TTP->getTypeConstraint ())
259259 SemaRef.SubstTypeConstraint (NewTTP, TC, Args,
260- /* EvaluateConstraint=*/ true );
260+ /* EvaluateConstraint=*/ EvaluateConstraint );
261261 if (TTP->hasDefaultArgument ()) {
262262 TemplateArgumentLoc InstantiatedDefaultArg;
263263 if (!SemaRef.SubstTemplateArgument (
@@ -284,6 +284,22 @@ transformTemplateParam(Sema &SemaRef, DeclContext *DC,
284284 return NewParam;
285285}
286286
287+ NamedDecl *transformTemplateParameter (Sema &SemaRef, DeclContext *DC,
288+ NamedDecl *TemplateParam,
289+ MultiLevelTemplateArgumentList &Args,
290+ unsigned NewIndex, unsigned NewDepth,
291+ bool EvaluateConstraint = true ) {
292+ if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
293+ return transformTemplateTypeParam (
294+ SemaRef, DC, TTP, Args, NewDepth, NewIndex,
295+ /* EvaluateConstraint=*/ EvaluateConstraint);
296+ if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
297+ return transformTemplateParam (SemaRef, DC, TTP, Args, NewIndex, NewDepth);
298+ if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
299+ return transformTemplateParam (SemaRef, DC, NTTP, Args, NewIndex, NewDepth);
300+ llvm_unreachable (" Unhandled template parameter types" );
301+ }
302+
287303// / Transform to convert portions of a constructor declaration into the
288304// / corresponding deduction guide, per C++1z [over.match.class.deduct]p1.
289305struct ConvertConstructorToDeductionGuideTransform {
@@ -358,20 +374,21 @@ struct ConvertConstructorToDeductionGuideTransform {
358374 Args.addOuterRetainedLevel ();
359375 if (NestedPattern)
360376 Args.addOuterRetainedLevels (NestedPattern->getTemplateDepth ());
361- NamedDecl *NewParam = transformTemplateParameter (Param, Args);
377+ auto [Depth, Index] = getDepthAndIndex (Param);
378+ NamedDecl *NewParam = transformTemplateParameter (
379+ SemaRef, DC, Param, Args, Index + Depth1IndexAdjustment, Depth - 1 );
362380 if (!NewParam)
363381 return nullptr ;
364382 // Constraints require that we substitute depth-1 arguments
365383 // to match depths when substituted for evaluation later
366384 Depth1Args.push_back (SemaRef.Context .getInjectedTemplateArg (NewParam));
367385
368386 if (NestedPattern) {
369- TemplateDeclInstantiator Instantiator (SemaRef, DC,
370- OuterInstantiationArgs);
371- Instantiator.setEvaluateConstraints (false );
372- SemaRef.runWithSufficientStackSpace (NewParam->getLocation (), [&] {
373- NewParam = cast<NamedDecl>(Instantiator.Visit (NewParam));
374- });
387+ auto [Depth, Index] = getDepthAndIndex (NewParam);
388+ NewParam = transformTemplateParameter (
389+ SemaRef, DC, NewParam, OuterInstantiationArgs, Index,
390+ Depth - OuterInstantiationArgs.getNumSubstitutedLevels (),
391+ /* EvaluateConstraint=*/ false );
375392 }
376393
377394 assert (NewParam->getTemplateDepth () == 0 &&
@@ -479,25 +496,6 @@ struct ConvertConstructorToDeductionGuideTransform {
479496 }
480497
481498private:
482- // / Transform a constructor template parameter into a deduction guide template
483- // / parameter, rebuilding any internal references to earlier parameters and
484- // / renumbering as we go.
485- NamedDecl *transformTemplateParameter (NamedDecl *TemplateParam,
486- MultiLevelTemplateArgumentList &Args) {
487- if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
488- return transformTemplateTypeParam (
489- SemaRef, DC, TTP, Args, TTP->getDepth () - 1 ,
490- Depth1IndexAdjustment + TTP->getIndex ());
491- if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
492- return transformTemplateParam (SemaRef, DC, TTP, Args,
493- Depth1IndexAdjustment + TTP->getIndex (),
494- TTP->getDepth () - 1 );
495- auto *NTTP = cast<NonTypeTemplateParmDecl>(TemplateParam);
496- return transformTemplateParam (SemaRef, DC, NTTP, Args,
497- Depth1IndexAdjustment + NTTP->getIndex (),
498- NTTP->getDepth () - 1 );
499- }
500-
501499 QualType transformFunctionProtoType (
502500 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL,
503501 SmallVectorImpl<ParmVarDecl *> &Params,
@@ -634,26 +632,6 @@ struct ConvertConstructorToDeductionGuideTransform {
634632 }
635633};
636634
637- unsigned getTemplateParameterDepth (NamedDecl *TemplateParam) {
638- if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
639- return TTP->getDepth ();
640- if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
641- return TTP->getDepth ();
642- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
643- return NTTP->getDepth ();
644- llvm_unreachable (" Unhandled template parameter types" );
645- }
646-
647- unsigned getTemplateParameterIndex (NamedDecl *TemplateParam) {
648- if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
649- return TTP->getIndex ();
650- if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
651- return TTP->getIndex ();
652- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
653- return NTTP->getIndex ();
654- llvm_unreachable (" Unhandled template parameter types" );
655- }
656-
657635// Find all template parameters that appear in the given DeducedArgs.
658636// Return the indices of the template parameters in the TemplateParams.
659637SmallVector<unsigned > TemplateParamsReferencedInTemplateArgumentList (
@@ -689,8 +667,10 @@ SmallVector<unsigned> TemplateParamsReferencedInTemplateArgumentList(
689667
690668 void MarkAppeared (NamedDecl *ND) {
691669 if (llvm::isa<NonTypeTemplateParmDecl, TemplateTypeParmDecl,
692- TemplateTemplateParmDecl>(ND))
693- Mark (getTemplateParameterDepth (ND), getTemplateParameterIndex (ND));
670+ TemplateTemplateParmDecl>(ND)) {
671+ auto [Depth, Index] = getDepthAndIndex (ND);
672+ Mark (Depth, Index);
673+ }
694674 }
695675 void Mark (unsigned Depth, unsigned Index) {
696676 if (Index < TemplateParamList->size () &&
@@ -722,20 +702,6 @@ bool hasDeclaredDeductionGuides(DeclarationName Name, DeclContext *DC) {
722702 return false ;
723703}
724704
725- NamedDecl *transformTemplateParameter (Sema &SemaRef, DeclContext *DC,
726- NamedDecl *TemplateParam,
727- MultiLevelTemplateArgumentList &Args,
728- unsigned NewIndex, unsigned NewDepth) {
729- if (auto *TTP = dyn_cast<TemplateTypeParmDecl>(TemplateParam))
730- return transformTemplateTypeParam (SemaRef, DC, TTP, Args, NewDepth,
731- NewIndex);
732- if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(TemplateParam))
733- return transformTemplateParam (SemaRef, DC, TTP, Args, NewIndex, NewDepth);
734- if (auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TemplateParam))
735- return transformTemplateParam (SemaRef, DC, NTTP, Args, NewIndex, NewDepth);
736- llvm_unreachable (" Unhandled template parameter types" );
737- }
738-
739705// Build the associated constraints for the alias deduction guides.
740706// C++ [over.match.class.deduct]p3.3:
741707// The associated constraints ([temp.constr.decl]) are the conjunction of the
@@ -791,7 +757,7 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
791757 NamedDecl *NewParam = transformTemplateParameter (
792758 SemaRef, AliasTemplate->getDeclContext (), TP, Args,
793759 /* NewIndex=*/ AdjustedAliasTemplateArgs.size (),
794- getTemplateParameterDepth (TP) + AdjustDepth);
760+ getDepthAndIndex (TP). first + AdjustDepth);
795761
796762 TemplateArgument NewTemplateArgument =
797763 Context.getInjectedTemplateArg (NewParam);
@@ -814,10 +780,10 @@ buildAssociatedConstraints(Sema &SemaRef, FunctionTemplateDecl *F,
814780 Args.setKind (TemplateSubstitutionKind::Rewrite);
815781 Args.addOuterTemplateArguments (TemplateArgsForBuildingRC);
816782 // Rebuild the template parameter with updated depth and index.
817- NamedDecl *NewParam = transformTemplateParameter (
818- SemaRef, F->getDeclContext (), TP, Args,
819- /* NewIndex=*/ FirstUndeducedParamIdx,
820- getTemplateParameterDepth (TP) + AdjustDepth);
783+ NamedDecl *NewParam =
784+ transformTemplateParameter ( SemaRef, F->getDeclContext (), TP, Args,
785+ /* NewIndex=*/ FirstUndeducedParamIdx,
786+ getDepthAndIndex (TP). first + AdjustDepth);
821787 FirstUndeducedParamIdx += 1 ;
822788 assert (TemplateArgsForBuildingRC[Index].isNull ());
823789 TemplateArgsForBuildingRC[Index] =
@@ -919,7 +885,7 @@ Expr *buildIsDeducibleConstraint(Sema &SemaRef,
919885 NamedDecl *NewParam = transformTemplateParameter (
920886 SemaRef, AliasTemplate->getDeclContext (), TP, Args,
921887 /* NewIndex=*/ TransformedTemplateArgs.size (),
922- getTemplateParameterDepth (TP) + AdjustDepth);
888+ getDepthAndIndex (TP). first + AdjustDepth);
923889
924890 TemplateArgument NewTemplateArgument =
925891 Context.getInjectedTemplateArg (NewParam);
@@ -1081,8 +1047,7 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
10811047 Args.addOuterTemplateArguments (TransformedDeducedAliasArgs);
10821048 NamedDecl *NewParam = transformTemplateParameter (
10831049 SemaRef, AliasTemplate->getDeclContext (), TP, Args,
1084- /* NewIndex=*/ FPrimeTemplateParams.size (),
1085- getTemplateParameterDepth (TP));
1050+ /* NewIndex=*/ FPrimeTemplateParams.size (), getDepthAndIndex (TP).first );
10861051 FPrimeTemplateParams.push_back (NewParam);
10871052
10881053 TemplateArgument NewTemplateArgument =
@@ -1101,7 +1066,7 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
11011066 Args.addOuterTemplateArguments (TemplateArgsForBuildingFPrime);
11021067 NamedDecl *NewParam = transformTemplateParameter (
11031068 SemaRef, F->getDeclContext (), TP, Args, FPrimeTemplateParams.size (),
1104- getTemplateParameterDepth (TP));
1069+ getDepthAndIndex (TP). first );
11051070 FPrimeTemplateParams.push_back (NewParam);
11061071
11071072 assert (TemplateArgsForBuildingFPrime[FTemplateParamIdx].isNull () &&
0 commit comments