@@ -11314,9 +11314,6 @@ class Sema final : public SemaBase {
1131411314 InventedParameterInfos.end());
1131511315 }
1131611316
11317- /// The number of SFINAE diagnostics that have been trapped.
11318- unsigned NumSFINAEErrors;
11319-
1132011317 ArrayRef<sema::FunctionScopeInfo *> getFunctionScopes() const {
1132111318 return llvm::ArrayRef(FunctionScopes.begin() + FunctionScopesStart,
1132211319 FunctionScopes.end());
@@ -12394,45 +12391,65 @@ class Sema final : public SemaBase {
1239412391 /// failures rather than hard errors.
1239512392 bool AccessCheckingSFINAE;
1239612393
12394+ class SFINAETrap;
12395+
12396+ struct SFINAEContextBase {
12397+ SFINAEContextBase(Sema &S, SFINAETrap *Cur)
12398+ : S(S), Prev(std::exchange(S.CurrentSFINAEContext, Cur)) {}
12399+
12400+ protected:
12401+ Sema &S;
12402+ ~SFINAEContextBase() { S.CurrentSFINAEContext = Prev; }
12403+
12404+ private:
12405+ SFINAETrap *Prev;
12406+ };
12407+
12408+ struct NonSFINAEContext : SFINAEContextBase {
12409+ NonSFINAEContext(Sema &S) : SFINAEContextBase(S, nullptr) {}
12410+ };
12411+
1239712412 /// RAII class used to determine whether SFINAE has
1239812413 /// trapped any errors that occur during template argument
1239912414 /// deduction.
12400- class SFINAETrap {
12401- Sema &SemaRef;
12402- unsigned PrevSFINAEErrors;
12403- bool PrevInNonInstantiationSFINAEContext;
12404- bool PrevAccessCheckingSFINAE;
12405- bool PrevLastDiagnosticIgnored;
12415+ class SFINAETrap : SFINAEContextBase {
12416+ bool HasErrorOcurred = false;
12417+ bool PrevAccessCheckingSFINAE = S.AccessCheckingSFINAE;
12418+ bool PrevLastDiagnosticIgnored =
12419+ S.getDiagnostics().isLastDiagnosticIgnored();
12420+ sema::TemplateDeductionInfo *DeductionInfo = nullptr;
12421+
12422+ SFINAETrap(Sema &S, sema::TemplateDeductionInfo *Info,
12423+ bool ForValidityCheck)
12424+ : SFINAEContextBase(S, this), DeductionInfo(Info) {
12425+ S.AccessCheckingSFINAE = ForValidityCheck;
12426+ }
1240612427
1240712428 public:
1240812429 /// \param ForValidityCheck If true, discard all diagnostics (from the
1240912430 /// immediate context) instead of adding them to the currently active
12410- /// \ref TemplateDeductionInfo (as returned by \ref isSFINAEContext).
12411- explicit SFINAETrap(Sema &SemaRef, bool ForValidityCheck = false)
12412- : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors),
12413- PrevInNonInstantiationSFINAEContext(
12414- SemaRef.InNonInstantiationSFINAEContext),
12415- PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE),
12416- PrevLastDiagnosticIgnored(
12417- SemaRef.getDiagnostics().isLastDiagnosticIgnored()) {
12418- if (ForValidityCheck || !SemaRef.isSFINAEContext())
12419- SemaRef.InNonInstantiationSFINAEContext = true;
12420- SemaRef.AccessCheckingSFINAE = ForValidityCheck;
12421- }
12431+ /// \ref TemplateDeductionInfo.
12432+ explicit SFINAETrap(Sema &S, bool ForValidityCheck = false)
12433+ : SFINAETrap(S, /*Info=*/nullptr, ForValidityCheck) {}
12434+
12435+ SFINAETrap(Sema &S, sema::TemplateDeductionInfo &Info)
12436+ : SFINAETrap(S, &Info, /*ForValidityCheck=*/false) {}
1242212437
1242312438 ~SFINAETrap() {
12424- SemaRef.NumSFINAEErrors = PrevSFINAEErrors;
12425- SemaRef.InNonInstantiationSFINAEContext =
12426- PrevInNonInstantiationSFINAEContext;
12427- SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE;
12428- SemaRef.getDiagnostics().setLastDiagnosticIgnored(
12429- PrevLastDiagnosticIgnored);
12439+ S.AccessCheckingSFINAE = PrevAccessCheckingSFINAE;
12440+ S.getDiagnostics().setLastDiagnosticIgnored(PrevLastDiagnosticIgnored);
1243012441 }
1243112442
12432- /// Determine whether any SFINAE errors have been trapped.
12433- bool hasErrorOccurred() const {
12434- return SemaRef.NumSFINAEErrors > PrevSFINAEErrors;
12443+ SFINAETrap(const SFINAETrap &) = delete;
12444+ SFINAETrap &operator=(const SFINAETrap &) = delete;
12445+
12446+ sema::TemplateDeductionInfo *getDeductionInfo() const {
12447+ return DeductionInfo;
1243512448 }
12449+
12450+ /// Determine whether any SFINAE errors have been trapped.
12451+ bool hasErrorOccurred() const { return HasErrorOcurred; }
12452+ void setErrorOccurred() { HasErrorOcurred = true; }
1243612453 };
1243712454
1243812455 /// RAII class used to indicate that we are performing provisional
@@ -13153,9 +13170,6 @@ class Sema final : public SemaBase {
1315313170 PartialOrderingTTP,
1315413171 } Kind;
1315513172
13156- /// Was the enclosing context a non-instantiation SFINAE context?
13157- bool SavedInNonInstantiationSFINAEContext;
13158-
1315913173 /// Whether we're substituting into constraints.
1316013174 bool InConstraintSubstitution;
1316113175
@@ -13200,22 +13214,15 @@ class Sema final : public SemaBase {
1320013214 return {TemplateArgs, NumTemplateArgs};
1320113215 }
1320213216
13203- /// The template deduction info object associated with the
13204- /// substitution or checking of explicit or deduced template arguments.
13205- sema::TemplateDeductionInfo *DeductionInfo;
13206-
1320713217 /// The source range that covers the construct that cause
1320813218 /// the instantiation, e.g., the template-id that causes a class
1320913219 /// template instantiation.
1321013220 SourceRange InstantiationRange;
1321113221
1321213222 CodeSynthesisContext()
13213- : Kind(TemplateInstantiation),
13214- SavedInNonInstantiationSFINAEContext(false),
13215- InConstraintSubstitution(false),
13223+ : Kind(TemplateInstantiation), InConstraintSubstitution(false),
1321613224 InParameterMappingSubstitution(false), Entity(nullptr),
13217- Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0),
13218- DeductionInfo(nullptr) {}
13225+ Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0) {}
1321913226
1322013227 /// Determines whether this template is an actual instantiation
1322113228 /// that should be counted toward the maximum instantiation depth.
@@ -13267,15 +13274,13 @@ class Sema final : public SemaBase {
1326713274 FunctionTemplateDecl *FunctionTemplate,
1326813275 ArrayRef<TemplateArgument> TemplateArgs,
1326913276 CodeSynthesisContext::SynthesisKind Kind,
13270- sema::TemplateDeductionInfo &DeductionInfo,
1327113277 SourceRange InstantiationRange = SourceRange());
1327213278
1327313279 /// Note that we are instantiating as part of template
1327413280 /// argument deduction for a class template declaration.
1327513281 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1327613282 TemplateDecl *Template,
1327713283 ArrayRef<TemplateArgument> TemplateArgs,
13278- sema::TemplateDeductionInfo &DeductionInfo,
1327913284 SourceRange InstantiationRange = SourceRange());
1328013285
1328113286 /// Note that we are instantiating as part of template
@@ -13284,7 +13289,6 @@ class Sema final : public SemaBase {
1328413289 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1328513290 ClassTemplatePartialSpecializationDecl *PartialSpec,
1328613291 ArrayRef<TemplateArgument> TemplateArgs,
13287- sema::TemplateDeductionInfo &DeductionInfo,
1328813292 SourceRange InstantiationRange = SourceRange());
1328913293
1329013294 /// Note that we are instantiating as part of template
@@ -13293,7 +13297,6 @@ class Sema final : public SemaBase {
1329313297 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1329413298 VarTemplatePartialSpecializationDecl *PartialSpec,
1329513299 ArrayRef<TemplateArgument> TemplateArgs,
13296- sema::TemplateDeductionInfo &DeductionInfo,
1329713300 SourceRange InstantiationRange = SourceRange());
1329813301
1329913302 /// Note that we are instantiating a default argument for a function
@@ -13339,7 +13342,6 @@ class Sema final : public SemaBase {
1333913342 /// concept.
1334013343 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1334113344 ConstraintSubstitution, NamedDecl *Template,
13342- sema::TemplateDeductionInfo &DeductionInfo,
1334313345 SourceRange InstantiationRange);
1334413346
1334513347 struct ConstraintNormalization {};
@@ -13359,7 +13361,6 @@ class Sema final : public SemaBase {
1335913361 /// a requirement of a requires expression.
1336013362 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1336113363 concepts::Requirement *Req,
13362- sema::TemplateDeductionInfo &DeductionInfo,
1336313364 SourceRange InstantiationRange = SourceRange());
1336413365
1336513366 /// \brief Note that we are checking the satisfaction of the constraint
@@ -13371,7 +13372,6 @@ class Sema final : public SemaBase {
1337113372 /// \brief Note that we are checking a requires clause.
1337213373 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1337313374 const RequiresExpr *E,
13374- sema::TemplateDeductionInfo &DeductionInfo,
1337513375 SourceRange InstantiationRange);
1337613376
1337713377 struct BuildingDeductionGuidesTag {};
@@ -13404,8 +13404,7 @@ class Sema final : public SemaBase {
1340413404 SourceLocation PointOfInstantiation,
1340513405 SourceRange InstantiationRange, Decl *Entity,
1340613406 NamedDecl *Template = nullptr,
13407- ArrayRef<TemplateArgument> TemplateArgs = {},
13408- sema::TemplateDeductionInfo *DeductionInfo = nullptr);
13407+ ArrayRef<TemplateArgument> TemplateArgs = {});
1340913408
1341013409 InstantiatingTemplate(const InstantiatingTemplate &) = delete;
1341113410
@@ -13546,12 +13545,7 @@ class Sema final : public SemaBase {
1354613545 /// recent visible declaration of that namespace.
1354713546 llvm::DenseMap<NamedDecl *, NamedDecl *> VisibleNamespaceCache;
1354813547
13549- /// Whether we are in a SFINAE context that is not associated with
13550- /// template instantiation.
13551- ///
13552- /// This is used when setting up a SFINAE trap (\c see SFINAETrap) outside
13553- /// of a template instantiation or template argument deduction.
13554- bool InNonInstantiationSFINAEContext;
13548+ SFINAETrap *CurrentSFINAEContext = nullptr;
1355513549
1355613550 /// The number of \p CodeSynthesisContexts that are not template
1355713551 /// instantiations and, therefore, should not be counted as part of the
@@ -13622,15 +13616,13 @@ class Sema final : public SemaBase {
1362213616 PrintInstantiationStack(getDefaultDiagFunc());
1362313617 }
1362413618
13625- /// Determines whether we are currently in a context where
13626- /// template argument substitution failures are not considered
13627- /// errors.
13628- ///
13629- /// \returns An empty \c Optional if we're not in a SFINAE context.
13630- /// Otherwise, contains a pointer that, if non-NULL, contains the nearest
13631- /// template-deduction context object, which can be used to capture
13632- /// diagnostics that will be suppressed.
13633- std::optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
13619+ /// Returns a pointer to the current SFINAE context, if any.
13620+ [[nodiscard]] SFINAETrap *getSFINAEContext() const {
13621+ return CurrentSFINAEContext;
13622+ }
13623+ [[nodiscard]] bool isSFINAEContext() const {
13624+ return CurrentSFINAEContext != nullptr;
13625+ }
1363413626
1363513627 /// Perform substitution on the type T with a given set of template
1363613628 /// arguments.
@@ -14642,7 +14634,8 @@ class Sema final : public SemaBase {
1464214634 ArrayRef<UnexpandedParameterPack> Unexpanded,
1464314635 const MultiLevelTemplateArgumentList &TemplateArgs,
1464414636 bool FailOnPackProducingTemplates, bool &ShouldExpand,
14645- bool &RetainExpansion, UnsignedOrNone &NumExpansions);
14637+ bool &RetainExpansion, UnsignedOrNone &NumExpansions,
14638+ bool Diagnose = true);
1464614639
1464714640 /// Determine the number of arguments in the given pack expansion
1464814641 /// type.
0 commit comments