@@ -11318,9 +11318,6 @@ class Sema final : public SemaBase {
1131811318 InventedParameterInfos.end());
1131911319 }
1132011320
11321- /// The number of SFINAE diagnostics that have been trapped.
11322- unsigned NumSFINAEErrors;
11323-
1132411321 ArrayRef<sema::FunctionScopeInfo *> getFunctionScopes() const {
1132511322 return llvm::ArrayRef(FunctionScopes.begin() + FunctionScopesStart,
1132611323 FunctionScopes.end());
@@ -12398,45 +12395,65 @@ class Sema final : public SemaBase {
1239812395 /// failures rather than hard errors.
1239912396 bool AccessCheckingSFINAE;
1240012397
12398+ class SFINAETrap;
12399+
12400+ struct SFINAEContextBase {
12401+ SFINAEContextBase(Sema &S, SFINAETrap *Cur)
12402+ : S(S), Prev(std::exchange(S.CurrentSFINAEContext, Cur)) {}
12403+
12404+ protected:
12405+ Sema &S;
12406+ ~SFINAEContextBase() { S.CurrentSFINAEContext = Prev; }
12407+
12408+ private:
12409+ SFINAETrap *Prev;
12410+ };
12411+
12412+ struct NonSFINAEContext : SFINAEContextBase {
12413+ NonSFINAEContext(Sema &S) : SFINAEContextBase(S, nullptr) {}
12414+ };
12415+
1240112416 /// RAII class used to determine whether SFINAE has
1240212417 /// trapped any errors that occur during template argument
1240312418 /// deduction.
12404- class SFINAETrap {
12405- Sema &SemaRef;
12406- unsigned PrevSFINAEErrors;
12407- bool PrevInNonInstantiationSFINAEContext;
12408- bool PrevAccessCheckingSFINAE;
12409- bool PrevLastDiagnosticIgnored;
12419+ class SFINAETrap : SFINAEContextBase {
12420+ bool HasErrorOcurred = false;
12421+ bool PrevAccessCheckingSFINAE = S.AccessCheckingSFINAE;
12422+ bool PrevLastDiagnosticIgnored =
12423+ S.getDiagnostics().isLastDiagnosticIgnored();
12424+ sema::TemplateDeductionInfo *DeductionInfo = nullptr;
12425+
12426+ SFINAETrap(Sema &S, sema::TemplateDeductionInfo *Info,
12427+ bool ForValidityCheck)
12428+ : SFINAEContextBase(S, this), DeductionInfo(Info) {
12429+ S.AccessCheckingSFINAE = ForValidityCheck;
12430+ }
1241012431
1241112432 public:
1241212433 /// \param ForValidityCheck If true, discard all diagnostics (from the
1241312434 /// immediate context) instead of adding them to the currently active
1241412435 /// \ref TemplateDeductionInfo (as returned by \ref isSFINAEContext).
12415- explicit SFINAETrap(Sema &SemaRef, bool ForValidityCheck = false)
12416- : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors),
12417- PrevInNonInstantiationSFINAEContext(
12418- SemaRef.InNonInstantiationSFINAEContext),
12419- PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE),
12420- PrevLastDiagnosticIgnored(
12421- SemaRef.getDiagnostics().isLastDiagnosticIgnored()) {
12422- if (ForValidityCheck || !SemaRef.isSFINAEContext())
12423- SemaRef.InNonInstantiationSFINAEContext = true;
12424- SemaRef.AccessCheckingSFINAE = ForValidityCheck;
12425- }
12436+ explicit SFINAETrap(Sema &S, bool ForValidityCheck = false)
12437+ : SFINAETrap(S, /*Info=*/nullptr, ForValidityCheck) {}
12438+
12439+ SFINAETrap(Sema &S, sema::TemplateDeductionInfo &Info)
12440+ : SFINAETrap(S, &Info, /*ForValidityCheck=*/false) {}
1242612441
1242712442 ~SFINAETrap() {
12428- SemaRef.NumSFINAEErrors = PrevSFINAEErrors;
12429- SemaRef.InNonInstantiationSFINAEContext =
12430- PrevInNonInstantiationSFINAEContext;
12431- SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE;
12432- SemaRef.getDiagnostics().setLastDiagnosticIgnored(
12433- PrevLastDiagnosticIgnored);
12443+ S.AccessCheckingSFINAE = PrevAccessCheckingSFINAE;
12444+ S.getDiagnostics().setLastDiagnosticIgnored(PrevLastDiagnosticIgnored);
1243412445 }
1243512446
12436- /// Determine whether any SFINAE errors have been trapped.
12437- bool hasErrorOccurred() const {
12438- return SemaRef.NumSFINAEErrors > PrevSFINAEErrors;
12447+ SFINAETrap(const SFINAETrap &) = delete;
12448+ SFINAETrap &operator=(const SFINAETrap &) = delete;
12449+
12450+ sema::TemplateDeductionInfo *getDeductionInfo() const {
12451+ return DeductionInfo;
1243912452 }
12453+
12454+ /// Determine whether any SFINAE errors have been trapped.
12455+ bool hasErrorOccurred() const { return HasErrorOcurred; }
12456+ void setErrorOccurred() { HasErrorOcurred = true; }
1244012457 };
1244112458
1244212459 /// RAII class used to indicate that we are performing provisional
@@ -13157,9 +13174,6 @@ class Sema final : public SemaBase {
1315713174 PartialOrderingTTP,
1315813175 } Kind;
1315913176
13160- /// Was the enclosing context a non-instantiation SFINAE context?
13161- bool SavedInNonInstantiationSFINAEContext;
13162-
1316313177 /// Whether we're substituting into constraints.
1316413178 bool InConstraintSubstitution;
1316513179
@@ -13204,22 +13218,15 @@ class Sema final : public SemaBase {
1320413218 return {TemplateArgs, NumTemplateArgs};
1320513219 }
1320613220
13207- /// The template deduction info object associated with the
13208- /// substitution or checking of explicit or deduced template arguments.
13209- sema::TemplateDeductionInfo *DeductionInfo;
13210-
1321113221 /// The source range that covers the construct that cause
1321213222 /// the instantiation, e.g., the template-id that causes a class
1321313223 /// template instantiation.
1321413224 SourceRange InstantiationRange;
1321513225
1321613226 CodeSynthesisContext()
13217- : Kind(TemplateInstantiation),
13218- SavedInNonInstantiationSFINAEContext(false),
13219- InConstraintSubstitution(false),
13227+ : Kind(TemplateInstantiation), InConstraintSubstitution(false),
1322013228 InParameterMappingSubstitution(false), Entity(nullptr),
13221- Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0),
13222- DeductionInfo(nullptr) {}
13229+ Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0) {}
1322313230
1322413231 /// Determines whether this template is an actual instantiation
1322513232 /// that should be counted toward the maximum instantiation depth.
@@ -13271,15 +13278,13 @@ class Sema final : public SemaBase {
1327113278 FunctionTemplateDecl *FunctionTemplate,
1327213279 ArrayRef<TemplateArgument> TemplateArgs,
1327313280 CodeSynthesisContext::SynthesisKind Kind,
13274- sema::TemplateDeductionInfo &DeductionInfo,
1327513281 SourceRange InstantiationRange = SourceRange());
1327613282
1327713283 /// Note that we are instantiating as part of template
1327813284 /// argument deduction for a class template declaration.
1327913285 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1328013286 TemplateDecl *Template,
1328113287 ArrayRef<TemplateArgument> TemplateArgs,
13282- sema::TemplateDeductionInfo &DeductionInfo,
1328313288 SourceRange InstantiationRange = SourceRange());
1328413289
1328513290 /// Note that we are instantiating as part of template
@@ -13288,7 +13293,6 @@ class Sema final : public SemaBase {
1328813293 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1328913294 ClassTemplatePartialSpecializationDecl *PartialSpec,
1329013295 ArrayRef<TemplateArgument> TemplateArgs,
13291- sema::TemplateDeductionInfo &DeductionInfo,
1329213296 SourceRange InstantiationRange = SourceRange());
1329313297
1329413298 /// Note that we are instantiating as part of template
@@ -13297,7 +13301,6 @@ class Sema final : public SemaBase {
1329713301 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1329813302 VarTemplatePartialSpecializationDecl *PartialSpec,
1329913303 ArrayRef<TemplateArgument> TemplateArgs,
13300- sema::TemplateDeductionInfo &DeductionInfo,
1330113304 SourceRange InstantiationRange = SourceRange());
1330213305
1330313306 /// Note that we are instantiating a default argument for a function
@@ -13343,7 +13346,6 @@ class Sema final : public SemaBase {
1334313346 /// concept.
1334413347 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1334513348 ConstraintSubstitution, NamedDecl *Template,
13346- sema::TemplateDeductionInfo &DeductionInfo,
1334713349 SourceRange InstantiationRange);
1334813350
1334913351 struct ConstraintNormalization {};
@@ -13363,7 +13365,6 @@ class Sema final : public SemaBase {
1336313365 /// a requirement of a requires expression.
1336413366 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1336513367 concepts::Requirement *Req,
13366- sema::TemplateDeductionInfo &DeductionInfo,
1336713368 SourceRange InstantiationRange = SourceRange());
1336813369
1336913370 /// \brief Note that we are checking the satisfaction of the constraint
@@ -13375,7 +13376,6 @@ class Sema final : public SemaBase {
1337513376 /// \brief Note that we are checking a requires clause.
1337613377 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1337713378 const RequiresExpr *E,
13378- sema::TemplateDeductionInfo &DeductionInfo,
1337913379 SourceRange InstantiationRange);
1338013380
1338113381 struct BuildingDeductionGuidesTag {};
@@ -13408,8 +13408,7 @@ class Sema final : public SemaBase {
1340813408 SourceLocation PointOfInstantiation,
1340913409 SourceRange InstantiationRange, Decl *Entity,
1341013410 NamedDecl *Template = nullptr,
13411- ArrayRef<TemplateArgument> TemplateArgs = {},
13412- sema::TemplateDeductionInfo *DeductionInfo = nullptr);
13411+ ArrayRef<TemplateArgument> TemplateArgs = {});
1341313412
1341413413 InstantiatingTemplate(const InstantiatingTemplate &) = delete;
1341513414
@@ -13550,12 +13549,7 @@ class Sema final : public SemaBase {
1355013549 /// recent visible declaration of that namespace.
1355113550 llvm::DenseMap<NamedDecl *, NamedDecl *> VisibleNamespaceCache;
1355213551
13553- /// Whether we are in a SFINAE context that is not associated with
13554- /// template instantiation.
13555- ///
13556- /// This is used when setting up a SFINAE trap (\c see SFINAETrap) outside
13557- /// of a template instantiation or template argument deduction.
13558- bool InNonInstantiationSFINAEContext;
13552+ SFINAETrap *CurrentSFINAEContext = nullptr;
1355913553
1356013554 /// The number of \p CodeSynthesisContexts that are not template
1356113555 /// instantiations and, therefore, should not be counted as part of the
@@ -13626,15 +13620,10 @@ class Sema final : public SemaBase {
1362613620 PrintInstantiationStack(getDefaultDiagFunc());
1362713621 }
1362813622
13629- /// Determines whether we are currently in a context where
13630- /// template argument substitution failures are not considered
13631- /// errors.
13632- ///
13633- /// \returns An empty \c Optional if we're not in a SFINAE context.
13634- /// Otherwise, contains a pointer that, if non-NULL, contains the nearest
13635- /// template-deduction context object, which can be used to capture
13636- /// diagnostics that will be suppressed.
13637- std::optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
13623+ /// Returns a pointer to the current SFINAE context, if any.
13624+ [[nodiscard]] SFINAETrap *getSFINAEContext() const {
13625+ return CurrentSFINAEContext;
13626+ }
1363813627
1363913628 /// Perform substitution on the type T with a given set of template
1364013629 /// arguments.
@@ -14646,7 +14635,8 @@ class Sema final : public SemaBase {
1464614635 ArrayRef<UnexpandedParameterPack> Unexpanded,
1464714636 const MultiLevelTemplateArgumentList &TemplateArgs,
1464814637 bool FailOnPackProducingTemplates, bool &ShouldExpand,
14649- bool &RetainExpansion, UnsignedOrNone &NumExpansions);
14638+ bool &RetainExpansion, UnsignedOrNone &NumExpansions,
14639+ bool Diagnose = true);
1465014640
1465114641 /// Determine the number of arguments in the given pack expansion
1465214642 /// type.
0 commit comments