@@ -11309,9 +11309,6 @@ class Sema final : public SemaBase {
1130911309 InventedParameterInfos.end());
1131011310 }
1131111311
11312- /// The number of SFINAE diagnostics that have been trapped.
11313- unsigned NumSFINAEErrors;
11314-
1131511312 ArrayRef<sema::FunctionScopeInfo *> getFunctionScopes() const {
1131611313 return llvm::ArrayRef(FunctionScopes.begin() + FunctionScopesStart,
1131711314 FunctionScopes.end());
@@ -12385,49 +12382,65 @@ class Sema final : public SemaBase {
1238512382 ///@{
1238612383
1238712384public:
12388- /// When true, access checking violations are treated as SFINAE
12389- /// failures rather than hard errors.
12390- bool AccessCheckingSFINAE;
12385+ class SFINAETrap;
12386+
12387+ struct SFINAEContextBase {
12388+ SFINAEContextBase(Sema &S, SFINAETrap *Cur)
12389+ : S(S), Prev(std::exchange(S.CurrentSFINAEContext, Cur)) {}
12390+
12391+ protected:
12392+ Sema &S;
12393+ ~SFINAEContextBase() { S.CurrentSFINAEContext = Prev; }
12394+
12395+ private:
12396+ SFINAETrap *Prev;
12397+ };
12398+
12399+ struct NonSFINAEContext : SFINAEContextBase {
12400+ NonSFINAEContext(Sema &S) : SFINAEContextBase(S, nullptr) {}
12401+ };
1239112402
1239212403 /// RAII class used to determine whether SFINAE has
1239312404 /// trapped any errors that occur during template argument
1239412405 /// deduction.
12395- class SFINAETrap {
12396- Sema &SemaRef;
12397- unsigned PrevSFINAEErrors;
12398- bool PrevInNonInstantiationSFINAEContext;
12399- bool PrevAccessCheckingSFINAE;
12400- bool PrevLastDiagnosticIgnored;
12406+ class SFINAETrap : SFINAEContextBase {
12407+ bool HasErrorOcurred = false;
12408+ bool WithAccessChecking = false;
12409+ bool PrevLastDiagnosticIgnored =
12410+ S.getDiagnostics().isLastDiagnosticIgnored();
12411+ sema::TemplateDeductionInfo *DeductionInfo = nullptr;
12412+
12413+ SFINAETrap(Sema &S, sema::TemplateDeductionInfo *Info,
12414+ bool WithAccessChecking)
12415+ : SFINAEContextBase(S, this), WithAccessChecking(WithAccessChecking),
12416+ DeductionInfo(Info) {}
1240112417
1240212418 public:
12403- /// \param ForValidityCheck If true, discard all diagnostics (from the
12419+ /// \param WithAccessChecking If true, discard all diagnostics (from the
1240412420 /// immediate context) instead of adding them to the currently active
12405- /// \ref TemplateDeductionInfo (as returned by \ref isSFINAEContext).
12406- explicit SFINAETrap(Sema &SemaRef, bool ForValidityCheck = false)
12407- : SemaRef(SemaRef), PrevSFINAEErrors(SemaRef.NumSFINAEErrors),
12408- PrevInNonInstantiationSFINAEContext(
12409- SemaRef.InNonInstantiationSFINAEContext),
12410- PrevAccessCheckingSFINAE(SemaRef.AccessCheckingSFINAE),
12411- PrevLastDiagnosticIgnored(
12412- SemaRef.getDiagnostics().isLastDiagnosticIgnored()) {
12413- if (ForValidityCheck || !SemaRef.isSFINAEContext())
12414- SemaRef.InNonInstantiationSFINAEContext = true;
12415- SemaRef.AccessCheckingSFINAE = ForValidityCheck;
12416- }
12421+ /// \ref TemplateDeductionInfo.
12422+ explicit SFINAETrap(Sema &S, bool WithAccessChecking = false)
12423+ : SFINAETrap(S, /*Info=*/nullptr, WithAccessChecking) {}
12424+
12425+ SFINAETrap(Sema &S, sema::TemplateDeductionInfo &Info)
12426+ : SFINAETrap(S, &Info, /*WithAccessChecking=*/false) {}
1241712427
1241812428 ~SFINAETrap() {
12419- SemaRef.NumSFINAEErrors = PrevSFINAEErrors;
12420- SemaRef.InNonInstantiationSFINAEContext =
12421- PrevInNonInstantiationSFINAEContext;
12422- SemaRef.AccessCheckingSFINAE = PrevAccessCheckingSFINAE;
12423- SemaRef.getDiagnostics().setLastDiagnosticIgnored(
12424- PrevLastDiagnosticIgnored);
12429+ S.getDiagnostics().setLastDiagnosticIgnored(PrevLastDiagnosticIgnored);
1242512430 }
1242612431
12427- /// Determine whether any SFINAE errors have been trapped.
12428- bool hasErrorOccurred() const {
12429- return SemaRef.NumSFINAEErrors > PrevSFINAEErrors;
12432+ SFINAETrap(const SFINAETrap &) = delete;
12433+ SFINAETrap &operator=(const SFINAETrap &) = delete;
12434+
12435+ sema::TemplateDeductionInfo *getDeductionInfo() const {
12436+ return DeductionInfo;
1243012437 }
12438+
12439+ /// Determine whether any SFINAE errors have been trapped.
12440+ bool hasErrorOccurred() const { return HasErrorOcurred; }
12441+ void setErrorOccurred() { HasErrorOcurred = true; }
12442+
12443+ bool withAccessChecking() const { return WithAccessChecking; }
1243112444 };
1243212445
1243312446 /// RAII class used to indicate that we are performing provisional
@@ -13148,9 +13161,6 @@ class Sema final : public SemaBase {
1314813161 PartialOrderingTTP,
1314913162 } Kind;
1315013163
13151- /// Was the enclosing context a non-instantiation SFINAE context?
13152- bool SavedInNonInstantiationSFINAEContext;
13153-
1315413164 /// Whether we're substituting into constraints.
1315513165 bool InConstraintSubstitution;
1315613166
@@ -13195,22 +13205,15 @@ class Sema final : public SemaBase {
1319513205 return {TemplateArgs, NumTemplateArgs};
1319613206 }
1319713207
13198- /// The template deduction info object associated with the
13199- /// substitution or checking of explicit or deduced template arguments.
13200- sema::TemplateDeductionInfo *DeductionInfo;
13201-
1320213208 /// The source range that covers the construct that cause
1320313209 /// the instantiation, e.g., the template-id that causes a class
1320413210 /// template instantiation.
1320513211 SourceRange InstantiationRange;
1320613212
1320713213 CodeSynthesisContext()
13208- : Kind(TemplateInstantiation),
13209- SavedInNonInstantiationSFINAEContext(false),
13210- InConstraintSubstitution(false),
13214+ : Kind(TemplateInstantiation), InConstraintSubstitution(false),
1321113215 InParameterMappingSubstitution(false), Entity(nullptr),
13212- Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0),
13213- DeductionInfo(nullptr) {}
13216+ Template(nullptr), TemplateArgs(nullptr), NumTemplateArgs(0) {}
1321413217
1321513218 /// Determines whether this template is an actual instantiation
1321613219 /// that should be counted toward the maximum instantiation depth.
@@ -13262,15 +13265,13 @@ class Sema final : public SemaBase {
1326213265 FunctionTemplateDecl *FunctionTemplate,
1326313266 ArrayRef<TemplateArgument> TemplateArgs,
1326413267 CodeSynthesisContext::SynthesisKind Kind,
13265- sema::TemplateDeductionInfo &DeductionInfo,
1326613268 SourceRange InstantiationRange = SourceRange());
1326713269
1326813270 /// Note that we are instantiating as part of template
1326913271 /// argument deduction for a class template declaration.
1327013272 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1327113273 TemplateDecl *Template,
1327213274 ArrayRef<TemplateArgument> TemplateArgs,
13273- sema::TemplateDeductionInfo &DeductionInfo,
1327413275 SourceRange InstantiationRange = SourceRange());
1327513276
1327613277 /// Note that we are instantiating as part of template
@@ -13279,7 +13280,6 @@ class Sema final : public SemaBase {
1327913280 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1328013281 ClassTemplatePartialSpecializationDecl *PartialSpec,
1328113282 ArrayRef<TemplateArgument> TemplateArgs,
13282- sema::TemplateDeductionInfo &DeductionInfo,
1328313283 SourceRange InstantiationRange = SourceRange());
1328413284
1328513285 /// Note that we are instantiating as part of template
@@ -13288,7 +13288,6 @@ class Sema final : public SemaBase {
1328813288 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1328913289 VarTemplatePartialSpecializationDecl *PartialSpec,
1329013290 ArrayRef<TemplateArgument> TemplateArgs,
13291- sema::TemplateDeductionInfo &DeductionInfo,
1329213291 SourceRange InstantiationRange = SourceRange());
1329313292
1329413293 /// Note that we are instantiating a default argument for a function
@@ -13334,7 +13333,6 @@ class Sema final : public SemaBase {
1333413333 /// concept.
1333513334 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1333613335 ConstraintSubstitution, NamedDecl *Template,
13337- sema::TemplateDeductionInfo &DeductionInfo,
1333813336 SourceRange InstantiationRange);
1333913337
1334013338 struct ConstraintNormalization {};
@@ -13354,7 +13352,6 @@ class Sema final : public SemaBase {
1335413352 /// a requirement of a requires expression.
1335513353 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1335613354 concepts::Requirement *Req,
13357- sema::TemplateDeductionInfo &DeductionInfo,
1335813355 SourceRange InstantiationRange = SourceRange());
1335913356
1336013357 /// \brief Note that we are checking the satisfaction of the constraint
@@ -13366,7 +13363,6 @@ class Sema final : public SemaBase {
1336613363 /// \brief Note that we are checking a requires clause.
1336713364 InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
1336813365 const RequiresExpr *E,
13369- sema::TemplateDeductionInfo &DeductionInfo,
1337013366 SourceRange InstantiationRange);
1337113367
1337213368 struct BuildingDeductionGuidesTag {};
@@ -13399,8 +13395,7 @@ class Sema final : public SemaBase {
1339913395 SourceLocation PointOfInstantiation,
1340013396 SourceRange InstantiationRange, Decl *Entity,
1340113397 NamedDecl *Template = nullptr,
13402- ArrayRef<TemplateArgument> TemplateArgs = {},
13403- sema::TemplateDeductionInfo *DeductionInfo = nullptr);
13398+ ArrayRef<TemplateArgument> TemplateArgs = {});
1340413399
1340513400 InstantiatingTemplate(const InstantiatingTemplate &) = delete;
1340613401
@@ -13541,12 +13536,7 @@ class Sema final : public SemaBase {
1354113536 /// recent visible declaration of that namespace.
1354213537 llvm::DenseMap<NamedDecl *, NamedDecl *> VisibleNamespaceCache;
1354313538
13544- /// Whether we are in a SFINAE context that is not associated with
13545- /// template instantiation.
13546- ///
13547- /// This is used when setting up a SFINAE trap (\c see SFINAETrap) outside
13548- /// of a template instantiation or template argument deduction.
13549- bool InNonInstantiationSFINAEContext;
13539+ SFINAETrap *CurrentSFINAEContext = nullptr;
1355013540
1355113541 /// The number of \p CodeSynthesisContexts that are not template
1355213542 /// instantiations and, therefore, should not be counted as part of the
@@ -13617,15 +13607,13 @@ class Sema final : public SemaBase {
1361713607 PrintInstantiationStack(getDefaultDiagFunc());
1361813608 }
1361913609
13620- /// Determines whether we are currently in a context where
13621- /// template argument substitution failures are not considered
13622- /// errors.
13623- ///
13624- /// \returns An empty \c Optional if we're not in a SFINAE context.
13625- /// Otherwise, contains a pointer that, if non-NULL, contains the nearest
13626- /// template-deduction context object, which can be used to capture
13627- /// diagnostics that will be suppressed.
13628- std::optional<sema::TemplateDeductionInfo *> isSFINAEContext() const;
13610+ /// Returns a pointer to the current SFINAE context, if any.
13611+ [[nodiscard]] SFINAETrap *getSFINAEContext() const {
13612+ return CurrentSFINAEContext;
13613+ }
13614+ [[nodiscard]] bool isSFINAEContext() const {
13615+ return CurrentSFINAEContext != nullptr;
13616+ }
1362913617
1363013618 /// Perform substitution on the type T with a given set of template
1363113619 /// arguments.
@@ -14637,7 +14625,8 @@ class Sema final : public SemaBase {
1463714625 ArrayRef<UnexpandedParameterPack> Unexpanded,
1463814626 const MultiLevelTemplateArgumentList &TemplateArgs,
1463914627 bool FailOnPackProducingTemplates, bool &ShouldExpand,
14640- bool &RetainExpansion, UnsignedOrNone &NumExpansions);
14628+ bool &RetainExpansion, UnsignedOrNone &NumExpansions,
14629+ bool Diagnose = true);
1464114630
1464214631 /// Determine the number of arguments in the given pack expansion
1464314632 /// type.
0 commit comments