@@ -639,8 +639,15 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
639639 }
640640
641641 Invalid = SemaRef.pushCodeSynthesisContext (Inst);
642- if (!Invalid)
642+ if (!Invalid) {
643+ AlreadyInstantiating =
644+ !Inst.Entity
645+ ? false
646+ : !SemaRef.InstantiatingSpecializations
647+ .insert ({Inst.Entity ->getCanonicalDecl (), Inst.Kind })
648+ .second ;
643649 atTemplateBegin (SemaRef.TemplateInstCallbacks , SemaRef, Inst);
650+ }
644651}
645652
646653Sema::InstantiatingTemplate::InstantiatingTemplate (
@@ -895,6 +902,13 @@ void Sema::popCodeSynthesisContext() {
895902
896903void Sema::InstantiatingTemplate::Clear () {
897904 if (!Invalid) {
905+ if (!AlreadyInstantiating) {
906+ auto &Active = SemaRef.CodeSynthesisContexts .back ();
907+ if (Active.Entity )
908+ SemaRef.InstantiatingSpecializations .erase (
909+ {Active.Entity ->getCanonicalDecl (), Active.Kind });
910+ }
911+
898912 atTemplateEnd (SemaRef.TemplateInstCallbacks , SemaRef,
899913 SemaRef.CodeSynthesisContexts .back ());
900914
@@ -3298,20 +3312,17 @@ bool Sema::SubstDefaultArgument(
32983312 FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext ());
32993313 Expr *PatternExpr = Param->getUninstantiatedDefaultArg ();
33003314
3301- RecursiveInstGuard AlreadyInstantiating (
3302- *this , Param, RecursiveInstGuard::Kind::DefaultArgument);
3303- if (AlreadyInstantiating) {
3304- Param->setInvalidDecl ();
3305- return Diag (Param->getBeginLoc (), diag::err_recursive_default_argument)
3306- << FD << PatternExpr->getSourceRange ();
3307- }
3308-
33093315 EnterExpressionEvaluationContext EvalContext (
33103316 *this , ExpressionEvaluationContext::PotentiallyEvaluated, Param);
33113317
33123318 InstantiatingTemplate Inst (*this , Loc, Param, TemplateArgs.getInnermost ());
33133319 if (Inst.isInvalid ())
33143320 return true ;
3321+ if (Inst.isAlreadyInstantiating ()) {
3322+ Diag (Param->getBeginLoc (), diag::err_recursive_default_argument) << FD;
3323+ Param->setInvalidDecl ();
3324+ return true ;
3325+ }
33153326
33163327 ExprResult Result;
33173328 // C++ [dcl.fct.default]p5:
@@ -3543,26 +3554,12 @@ namespace clang {
35433554 }
35443555}
35453556
3546- bool Sema::InstantiateClass (SourceLocation PointOfInstantiation,
3547- CXXRecordDecl *Instantiation,
3548- CXXRecordDecl *Pattern,
3549- const MultiLevelTemplateArgumentList &TemplateArgs,
3550- TemplateSpecializationKind TSK, bool Complain) {
3551- #ifndef NDEBUG
3552- RecursiveInstGuard AlreadyInstantiating (*this , Instantiation,
3553- RecursiveInstGuard::Kind::Template);
3554- assert (!AlreadyInstantiating && " should have been caught by caller" );
3555- #endif
3556-
3557- return InstantiateClassImpl (PointOfInstantiation, Instantiation, Pattern,
3558- TemplateArgs, TSK, Complain);
3559- }
3560-
3561- bool Sema::InstantiateClassImpl (
3562- SourceLocation PointOfInstantiation, CXXRecordDecl *Instantiation,
3563- CXXRecordDecl *Pattern, const MultiLevelTemplateArgumentList &TemplateArgs,
3564- TemplateSpecializationKind TSK, bool Complain) {
3565-
3557+ bool
3558+ Sema::InstantiateClass (SourceLocation PointOfInstantiation,
3559+ CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
3560+ const MultiLevelTemplateArgumentList &TemplateArgs,
3561+ TemplateSpecializationKind TSK,
3562+ bool Complain) {
35663563 CXXRecordDecl *PatternDef
35673564 = cast_or_null<CXXRecordDecl>(Pattern->getDefinition ());
35683565 if (DiagnoseUninstantiableTemplate (PointOfInstantiation, Instantiation,
@@ -3599,6 +3596,7 @@ bool Sema::InstantiateClassImpl(
35993596 InstantiatingTemplate Inst (*this , PointOfInstantiation, Instantiation);
36003597 if (Inst.isInvalid ())
36013598 return true ;
3599+ assert (!Inst.isAlreadyInstantiating () && " should have been caught by caller" );
36023600 PrettyDeclStackTraceEntry CrashInfo (Context, Instantiation, SourceLocation (),
36033601 " instantiating class definition" );
36043602
@@ -3810,12 +3808,6 @@ bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,
38103808 EnumDecl *Instantiation, EnumDecl *Pattern,
38113809 const MultiLevelTemplateArgumentList &TemplateArgs,
38123810 TemplateSpecializationKind TSK) {
3813- #ifndef NDEBUG
3814- RecursiveInstGuard AlreadyInstantiating (*this , Instantiation,
3815- RecursiveInstGuard::Kind::Template);
3816- assert (!AlreadyInstantiating && " should have been caught by caller" );
3817- #endif
3818-
38193811 EnumDecl *PatternDef = Pattern->getDefinition ();
38203812 if (DiagnoseUninstantiableTemplate (PointOfInstantiation, Instantiation,
38213813 Instantiation->getInstantiatedFromMemberEnum (),
@@ -3833,6 +3825,8 @@ bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,
38333825 InstantiatingTemplate Inst (*this , PointOfInstantiation, Instantiation);
38343826 if (Inst.isInvalid ())
38353827 return true ;
3828+ if (Inst.isAlreadyInstantiating ())
3829+ return false ;
38363830 PrettyDeclStackTraceEntry CrashInfo (Context, Instantiation, SourceLocation (),
38373831 " instantiating enum definition" );
38383832
@@ -3871,14 +3865,6 @@ bool Sema::InstantiateInClassInitializer(
38713865 Pattern->getInClassInitStyle () &&
38723866 " pattern and instantiation disagree about init style" );
38733867
3874- RecursiveInstGuard AlreadyInstantiating (*this , Instantiation,
3875- RecursiveInstGuard::Kind::Template);
3876- if (AlreadyInstantiating)
3877- // Error out if we hit an instantiation cycle for this initializer.
3878- return Diag (PointOfInstantiation,
3879- diag::err_default_member_initializer_cycle)
3880- << Instantiation;
3881-
38823868 // Error out if we haven't parsed the initializer of the pattern yet because
38833869 // we are waiting for the closing brace of the outer class.
38843870 Expr *OldInit = Pattern->getInClassInitializer ();
@@ -3897,6 +3883,12 @@ bool Sema::InstantiateInClassInitializer(
38973883 InstantiatingTemplate Inst (*this , PointOfInstantiation, Instantiation);
38983884 if (Inst.isInvalid ())
38993885 return true ;
3886+ if (Inst.isAlreadyInstantiating ()) {
3887+ // Error out if we hit an instantiation cycle for this initializer.
3888+ Diag (PointOfInstantiation, diag::err_default_member_initializer_cycle)
3889+ << Instantiation;
3890+ return true ;
3891+ }
39003892 PrettyDeclStackTraceEntry CrashInfo (Context, Instantiation, SourceLocation (),
39013893 " instantiating default member init" );
39023894
@@ -3980,6 +3972,8 @@ static ActionResult<CXXRecordDecl *> getPatternForClassTemplateSpecialization(
39803972 Sema::InstantiatingTemplate Inst (S, PointOfInstantiation, ClassTemplateSpec);
39813973 if (Inst.isInvalid ())
39823974 return {/* Invalid=*/ true };
3975+ if (Inst.isAlreadyInstantiating ())
3976+ return {/* Invalid=*/ false };
39833977
39843978 llvm::PointerUnion<ClassTemplateDecl *,
39853979 ClassTemplatePartialSpecializationDecl *>
@@ -4142,11 +4136,6 @@ bool Sema::InstantiateClassTemplateSpecialization(
41424136 if (ClassTemplateSpec->isInvalidDecl ())
41434137 return true ;
41444138
4145- Sema::RecursiveInstGuard AlreadyInstantiating (
4146- *this , ClassTemplateSpec, Sema::RecursiveInstGuard::Kind::Template);
4147- if (AlreadyInstantiating)
4148- return false ;
4149-
41504139 bool HadAvaibilityWarning =
41514140 ShouldDiagnoseAvailabilityOfDecl (ClassTemplateSpec, nullptr , nullptr )
41524141 .first != AR_Available;
@@ -4159,7 +4148,7 @@ bool Sema::InstantiateClassTemplateSpecialization(
41594148 if (!Pattern.isUsable ())
41604149 return Pattern.isInvalid ();
41614150
4162- bool Err = InstantiateClassImpl (
4151+ bool Err = InstantiateClass (
41634152 PointOfInstantiation, ClassTemplateSpec, Pattern.get (),
41644153 getTemplateInstantiationArgs (ClassTemplateSpec), TSK, Complain);
41654154
0 commit comments