@@ -639,15 +639,8 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
639639 }
640640
641641 Invalid = SemaRef.pushCodeSynthesisContext (Inst);
642- if (!Invalid) {
643- AlreadyInstantiating =
644- !Inst.Entity
645- ? false
646- : !SemaRef.InstantiatingSpecializations
647- .insert ({Inst.Entity ->getCanonicalDecl (), Inst.Kind })
648- .second ;
642+ if (!Invalid)
649643 atTemplateBegin (SemaRef.TemplateInstCallbacks , SemaRef, Inst);
650- }
651644}
652645
653646Sema::InstantiatingTemplate::InstantiatingTemplate (
@@ -902,13 +895,6 @@ void Sema::popCodeSynthesisContext() {
902895
903896void Sema::InstantiatingTemplate::Clear () {
904897 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-
912898 atTemplateEnd (SemaRef.TemplateInstCallbacks , SemaRef,
913899 SemaRef.CodeSynthesisContexts .back ());
914900
@@ -3312,17 +3298,20 @@ bool Sema::SubstDefaultArgument(
33123298 FunctionDecl *FD = cast<FunctionDecl>(Param->getDeclContext ());
33133299 Expr *PatternExpr = Param->getUninstantiatedDefaultArg ();
33143300
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+
33153309 EnterExpressionEvaluationContext EvalContext (
33163310 *this , ExpressionEvaluationContext::PotentiallyEvaluated, Param);
33173311
33183312 InstantiatingTemplate Inst (*this , Loc, Param, TemplateArgs.getInnermost ());
33193313 if (Inst.isInvalid ())
33203314 return true ;
3321- if (Inst.isAlreadyInstantiating ()) {
3322- Diag (Param->getBeginLoc (), diag::err_recursive_default_argument) << FD;
3323- Param->setInvalidDecl ();
3324- return true ;
3325- }
33263315
33273316 ExprResult Result;
33283317 // C++ [dcl.fct.default]p5:
@@ -3554,12 +3543,26 @@ namespace clang {
35543543 }
35553544}
35563545
3557- bool
3558- Sema::InstantiateClass (SourceLocation PointOfInstantiation,
3559- CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
3560- const MultiLevelTemplateArgumentList &TemplateArgs,
3561- TemplateSpecializationKind TSK,
3562- bool Complain) {
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+
35633566 CXXRecordDecl *PatternDef
35643567 = cast_or_null<CXXRecordDecl>(Pattern->getDefinition ());
35653568 if (DiagnoseUninstantiableTemplate (PointOfInstantiation, Instantiation,
@@ -3596,7 +3599,6 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
35963599 InstantiatingTemplate Inst (*this , PointOfInstantiation, Instantiation);
35973600 if (Inst.isInvalid ())
35983601 return true ;
3599- assert (!Inst.isAlreadyInstantiating () && " should have been caught by caller" );
36003602 PrettyDeclStackTraceEntry CrashInfo (Context, Instantiation, SourceLocation (),
36013603 " instantiating class definition" );
36023604
@@ -3808,6 +3810,12 @@ bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,
38083810 EnumDecl *Instantiation, EnumDecl *Pattern,
38093811 const MultiLevelTemplateArgumentList &TemplateArgs,
38103812 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+
38113819 EnumDecl *PatternDef = Pattern->getDefinition ();
38123820 if (DiagnoseUninstantiableTemplate (PointOfInstantiation, Instantiation,
38133821 Instantiation->getInstantiatedFromMemberEnum (),
@@ -3825,8 +3833,6 @@ bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,
38253833 InstantiatingTemplate Inst (*this , PointOfInstantiation, Instantiation);
38263834 if (Inst.isInvalid ())
38273835 return true ;
3828- if (Inst.isAlreadyInstantiating ())
3829- return false ;
38303836 PrettyDeclStackTraceEntry CrashInfo (Context, Instantiation, SourceLocation (),
38313837 " instantiating enum definition" );
38323838
@@ -3865,6 +3871,14 @@ bool Sema::InstantiateInClassInitializer(
38653871 Pattern->getInClassInitStyle () &&
38663872 " pattern and instantiation disagree about init style" );
38673873
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+
38683882 // Error out if we haven't parsed the initializer of the pattern yet because
38693883 // we are waiting for the closing brace of the outer class.
38703884 Expr *OldInit = Pattern->getInClassInitializer ();
@@ -3883,12 +3897,6 @@ bool Sema::InstantiateInClassInitializer(
38833897 InstantiatingTemplate Inst (*this , PointOfInstantiation, Instantiation);
38843898 if (Inst.isInvalid ())
38853899 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- }
38923900 PrettyDeclStackTraceEntry CrashInfo (Context, Instantiation, SourceLocation (),
38933901 " instantiating default member init" );
38943902
@@ -3972,8 +3980,6 @@ static ActionResult<CXXRecordDecl *> getPatternForClassTemplateSpecialization(
39723980 Sema::InstantiatingTemplate Inst (S, PointOfInstantiation, ClassTemplateSpec);
39733981 if (Inst.isInvalid ())
39743982 return {/* Invalid=*/ true };
3975- if (Inst.isAlreadyInstantiating ())
3976- return {/* Invalid=*/ false };
39773983
39783984 llvm::PointerUnion<ClassTemplateDecl *,
39793985 ClassTemplatePartialSpecializationDecl *>
@@ -4136,6 +4142,11 @@ bool Sema::InstantiateClassTemplateSpecialization(
41364142 if (ClassTemplateSpec->isInvalidDecl ())
41374143 return true ;
41384144
4145+ Sema::RecursiveInstGuard AlreadyInstantiating (
4146+ *this , ClassTemplateSpec, Sema::RecursiveInstGuard::Kind::Template);
4147+ if (AlreadyInstantiating)
4148+ return false ;
4149+
41394150 bool HadAvaibilityWarning =
41404151 ShouldDiagnoseAvailabilityOfDecl (ClassTemplateSpec, nullptr , nullptr )
41414152 .first != AR_Available;
@@ -4148,7 +4159,7 @@ bool Sema::InstantiateClassTemplateSpecialization(
41484159 if (!Pattern.isUsable ())
41494160 return Pattern.isInvalid ();
41504161
4151- bool Err = InstantiateClass (
4162+ bool Err = InstantiateClassImpl (
41524163 PointOfInstantiation, ClassTemplateSpec, Pattern.get (),
41534164 getTemplateInstantiationArgs (ClassTemplateSpec), TSK, Complain);
41544165
0 commit comments