[libcxx-commits] [clang] [libcxx] Revert "[Clang] Normalize constraints before checking for satisfaction" (PR #161669)
via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Oct 2 06:58:08 PDT 2025
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff origin/main HEAD --extensions cpp,h -- clang/include/clang/AST/ASTConcept.h clang/include/clang/AST/ASTContext.h clang/include/clang/Sema/Sema.h clang/include/clang/Sema/SemaConcept.h clang/include/clang/Sema/Template.h clang/lib/AST/ASTConcept.cpp clang/lib/AST/ASTImporter.cpp clang/lib/Sema/SemaConcept.cpp clang/lib/Sema/SemaDeclCXX.cpp clang/lib/Sema/SemaExprCXX.cpp clang/lib/Sema/SemaOverload.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateDeduction.cpp clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReaderDecl.cpp clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/test/AST/ast-dump-concepts.cpp clang/test/AST/ast-dump-ctad-alias.cpp clang/test/CXX/drs/cwg25xx.cpp clang/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp clang/test/CXX/temp/temp.constr/temp.constr.atomic/constrant-satisfaction-conversions.cpp clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp clang/test/CXX/temp/temp.param/p10-2a.cpp clang/test/SemaCXX/cxx23-assume.cpp clang/test/SemaCXX/cxx2b-deducing-this.cpp clang/test/SemaCXX/cxx2c-fold-exprs.cpp clang/test/SemaCXX/cxx2c-template-template-param.cpp clang/test/SemaCXX/invalid-requirement-requires-expr.cpp clang/test/SemaCXX/overload-resolution-deferred-templates.cpp clang/test/SemaCXX/type-traits.cpp clang/test/SemaTemplate/concepts-recovery-expr.cpp clang/test/SemaTemplate/concepts-recursive-inst.cpp clang/test/SemaTemplate/concepts.cpp clang/test/SemaTemplate/deduction-guide.cpp clang/test/SemaTemplate/instantiate-abbreviated-template.cpp clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp clang/test/SemaTemplate/instantiate-requires-expr.cpp clang/test/SemaTemplate/instantiate-template-argument.cpp clang/test/SemaTemplate/pr52970.cpp libcxx/test/libcxx/algorithms/cpp17_iterator_concepts.verify.cpp
``````````
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/clang/include/clang/Sema/SemaConcept.h b/clang/include/clang/Sema/SemaConcept.h
index 648a9c51a..df1d5a95d 100644
--- a/clang/include/clang/Sema/SemaConcept.h
+++ b/clang/include/clang/Sema/SemaConcept.h
@@ -77,15 +77,15 @@ struct NormalizedConstraint {
CompoundConstraint>
Constraint;
- NormalizedConstraint(AtomicConstraint *C): Constraint{C} { };
+ NormalizedConstraint(AtomicConstraint *C) : Constraint{C} {};
NormalizedConstraint(FoldExpandedConstraint *C) : Constraint{C} {};
NormalizedConstraint(ASTContext &C, NormalizedConstraint LHS,
NormalizedConstraint RHS, CompoundConstraintKind Kind);
NormalizedConstraint(ASTContext &C, const NormalizedConstraint &Other);
- NormalizedConstraint(NormalizedConstraint &&Other):
- Constraint(Other.Constraint) {
+ NormalizedConstraint(NormalizedConstraint &&Other)
+ : Constraint(Other.Constraint) {
Other.Constraint = nullptr;
}
NormalizedConstraint &operator=(const NormalizedConstraint &Other) = delete;
@@ -240,6 +240,6 @@ private:
uint16_t getNewLiteralId();
};
-} // clang
+} // namespace clang
#endif // LLVM_CLANG_SEMA_SEMACONCEPT_H
diff --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp
index d658890e0..c4e88223c 100644
--- a/clang/lib/AST/ASTConcept.cpp
+++ b/clang/lib/AST/ASTConcept.cpp
@@ -74,9 +74,10 @@ ASTConstraintSatisfaction *ASTConstraintSatisfaction::Rebuild(
return new (Mem) ASTConstraintSatisfaction(C, Satisfaction);
}
-void ConstraintSatisfaction::Profile(
- llvm::FoldingSetNodeID &ID, const ASTContext &C,
- const NamedDecl *ConstraintOwner, ArrayRef<TemplateArgument> TemplateArgs) {
+void ConstraintSatisfaction::Profile(llvm::FoldingSetNodeID &ID,
+ const ASTContext &C,
+ const NamedDecl *ConstraintOwner,
+ ArrayRef<TemplateArgument> TemplateArgs) {
ID.AddPointer(ConstraintOwner);
ID.AddInteger(TemplateArgs.size());
for (auto &Arg : TemplateArgs)
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index dc6d232d9..db2e596c1 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -85,7 +85,7 @@ public:
OK_Ordinary, Loc, FPOptionsOverride{});
}
};
-}
+} // namespace
bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression,
Token NextToken, bool *PossibleNonPrimary,
@@ -146,14 +146,14 @@ bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression,
if (!Context.hasSameUnqualifiedType(Type, Context.BoolTy)) {
Diag(ConstraintExpression->getExprLoc(),
- diag::err_non_bool_atomic_constraint) << Type
- << ConstraintExpression->getSourceRange();
+ diag::err_non_bool_atomic_constraint)
+ << Type << ConstraintExpression->getSourceRange();
CheckForNonPrimary();
return false;
}
if (PossibleNonPrimary)
- *PossibleNonPrimary = false;
+ *PossibleNonPrimary = false;
return true;
}
@@ -164,14 +164,14 @@ struct SatisfactionStackRAII {
SatisfactionStackRAII(Sema &SemaRef, const NamedDecl *ND,
const llvm::FoldingSetNodeID &FSNID)
: SemaRef(SemaRef) {
- if (ND) {
+ if (ND) {
SemaRef.PushSatisfactionStackEntry(ND, FSNID);
Inserted = true;
- }
+ }
}
~SatisfactionStackRAII() {
- if (Inserted)
- SemaRef.PopSatisfactionStackEntry();
+ if (Inserted)
+ SemaRef.PopSatisfactionStackEntry();
}
};
} // namespace
@@ -582,7 +582,8 @@ static bool CheckConstraintSatisfaction(
TemplateArgsLists.getNumSubstitutedLevels() > 0
? TemplateArgsLists.getOutermost()
: ArrayRef<TemplateArgument>{};
- Sema::InstantiatingTemplate Inst(S, TemplateIDRange.getBegin(),
+ Sema::InstantiatingTemplate Inst(
+ S, TemplateIDRange.getBegin(),
Sema::InstantiatingTemplate::ConstraintsCheck{},
const_cast<NamedDecl *>(Template), TemplateArgs, TemplateIDRange);
if (Inst.isInvalid())
@@ -854,7 +855,6 @@ bool Sema::CheckFunctionConstraints(const FunctionDecl *FD,
Satisfaction);
}
-
// Figure out the to-translation-unit depth for this function declaration for
// the purpose of seeing if they differ by constraints. This isn't the same as
// getTemplateDepth, because it includes already instantiated parents.
@@ -871,9 +871,10 @@ CalculateTemplateDepthForConstraints(Sema &S, const NamedDecl *ND,
}
namespace {
- class AdjustConstraintDepth : public TreeTransform<AdjustConstraintDepth> {
+class AdjustConstraintDepth : public TreeTransform<AdjustConstraintDepth> {
unsigned TemplateDepth = 0;
- public:
+
+public:
using inherited = TreeTransform<AdjustConstraintDepth>;
AdjustConstraintDepth(Sema &SemaRef, unsigned TemplateDepth)
: inherited(SemaRef), TemplateDepth(TemplateDepth) {}
@@ -895,7 +896,7 @@ namespace {
NewTL.setNameLoc(TL.getNameLoc());
return Result;
}
- };
+};
} // namespace
static const Expr *SubstituteConstraintExpressionWithoutSatisfaction(
@@ -1161,73 +1162,74 @@ bool Sema::CheckFunctionTemplateConstraints(
static void diagnoseUnsatisfiedRequirement(Sema &S,
concepts::ExprRequirement *Req,
bool First) {
- assert(!Req->isSatisfied()
- && "Diagnose() can only be used on an unsatisfied requirement");
+ assert(!Req->isSatisfied() &&
+ "Diagnose() can only be used on an unsatisfied requirement");
switch (Req->getSatisfactionStatus()) {
- case concepts::ExprRequirement::SS_Dependent:
- llvm_unreachable("Diagnosing a dependent requirement");
- break;
- case concepts::ExprRequirement::SS_ExprSubstitutionFailure: {
- auto *SubstDiag = Req->getExprSubstitutionDiagnostic();
- if (!SubstDiag->DiagMessage.empty())
- S.Diag(SubstDiag->DiagLoc,
- diag::note_expr_requirement_expr_substitution_error)
- << (int)First << SubstDiag->SubstitutedEntity
- << SubstDiag->DiagMessage;
- else
- S.Diag(SubstDiag->DiagLoc,
- diag::note_expr_requirement_expr_unknown_substitution_error)
- << (int)First << SubstDiag->SubstitutedEntity;
- break;
- }
- case concepts::ExprRequirement::SS_NoexceptNotMet:
- S.Diag(Req->getNoexceptLoc(),
- diag::note_expr_requirement_noexcept_not_met)
- << (int)First << Req->getExpr();
- break;
- case concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure: {
- auto *SubstDiag =
- Req->getReturnTypeRequirement().getSubstitutionDiagnostic();
- if (!SubstDiag->DiagMessage.empty())
- S.Diag(SubstDiag->DiagLoc,
- diag::note_expr_requirement_type_requirement_substitution_error)
- << (int)First << SubstDiag->SubstitutedEntity
- << SubstDiag->DiagMessage;
- else
- S.Diag(SubstDiag->DiagLoc,
- diag::note_expr_requirement_type_requirement_unknown_substitution_error)
- << (int)First << SubstDiag->SubstitutedEntity;
- break;
- }
- case concepts::ExprRequirement::SS_ConstraintsNotSatisfied: {
- ConceptSpecializationExpr *ConstraintExpr =
- Req->getReturnTypeRequirementSubstitutedConstraintExpr();
- if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
- // A simple case - expr type is the type being constrained and the concept
- // was not provided arguments.
- Expr *e = Req->getExpr();
- S.Diag(e->getBeginLoc(),
- diag::note_expr_requirement_constraints_not_satisfied_simple)
- << (int)First << S.Context.getReferenceQualifiedType(e)
- << ConstraintExpr->getNamedConcept();
- } else {
- S.Diag(ConstraintExpr->getBeginLoc(),
- diag::note_expr_requirement_constraints_not_satisfied)
- << (int)First << ConstraintExpr;
- }
- S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction());
- break;
+ case concepts::ExprRequirement::SS_Dependent:
+ llvm_unreachable("Diagnosing a dependent requirement");
+ break;
+ case concepts::ExprRequirement::SS_ExprSubstitutionFailure: {
+ auto *SubstDiag = Req->getExprSubstitutionDiagnostic();
+ if (!SubstDiag->DiagMessage.empty())
+ S.Diag(SubstDiag->DiagLoc,
+ diag::note_expr_requirement_expr_substitution_error)
+ << (int)First << SubstDiag->SubstitutedEntity
+ << SubstDiag->DiagMessage;
+ else
+ S.Diag(SubstDiag->DiagLoc,
+ diag::note_expr_requirement_expr_unknown_substitution_error)
+ << (int)First << SubstDiag->SubstitutedEntity;
+ break;
+ }
+ case concepts::ExprRequirement::SS_NoexceptNotMet:
+ S.Diag(Req->getNoexceptLoc(), diag::note_expr_requirement_noexcept_not_met)
+ << (int)First << Req->getExpr();
+ break;
+ case concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure: {
+ auto *SubstDiag =
+ Req->getReturnTypeRequirement().getSubstitutionDiagnostic();
+ if (!SubstDiag->DiagMessage.empty())
+ S.Diag(SubstDiag->DiagLoc,
+ diag::note_expr_requirement_type_requirement_substitution_error)
+ << (int)First << SubstDiag->SubstitutedEntity
+ << SubstDiag->DiagMessage;
+ else
+ S.Diag(
+ SubstDiag->DiagLoc,
+ diag::
+ note_expr_requirement_type_requirement_unknown_substitution_error)
+ << (int)First << SubstDiag->SubstitutedEntity;
+ break;
+ }
+ case concepts::ExprRequirement::SS_ConstraintsNotSatisfied: {
+ ConceptSpecializationExpr *ConstraintExpr =
+ Req->getReturnTypeRequirementSubstitutedConstraintExpr();
+ if (ConstraintExpr->getTemplateArgsAsWritten()->NumTemplateArgs == 1) {
+ // A simple case - expr type is the type being constrained and the concept
+ // was not provided arguments.
+ Expr *e = Req->getExpr();
+ S.Diag(e->getBeginLoc(),
+ diag::note_expr_requirement_constraints_not_satisfied_simple)
+ << (int)First << S.Context.getReferenceQualifiedType(e)
+ << ConstraintExpr->getNamedConcept();
+ } else {
+ S.Diag(ConstraintExpr->getBeginLoc(),
+ diag::note_expr_requirement_constraints_not_satisfied)
+ << (int)First << ConstraintExpr;
}
- case concepts::ExprRequirement::SS_Satisfied:
- llvm_unreachable("We checked this above");
+ S.DiagnoseUnsatisfiedConstraint(ConstraintExpr->getSatisfaction());
+ break;
+ }
+ case concepts::ExprRequirement::SS_Satisfied:
+ llvm_unreachable("We checked this above");
}
}
static void diagnoseUnsatisfiedRequirement(Sema &S,
concepts::TypeRequirement *Req,
bool First) {
- assert(!Req->isSatisfied()
- && "Diagnose() can only be used on an unsatisfied requirement");
+ assert(!Req->isSatisfied() &&
+ "Diagnose() can only be used on an unsatisfied requirement");
switch (Req->getSatisfactionStatus()) {
case concepts::TypeRequirement::SS_Dependent:
llvm_unreachable("Diagnosing a dependent requirement");
@@ -1235,9 +1237,9 @@ static void diagnoseUnsatisfiedRequirement(Sema &S,
case concepts::TypeRequirement::SS_SubstitutionFailure: {
auto *SubstDiag = Req->getSubstitutionDiagnostic();
if (!SubstDiag->DiagMessage.empty())
- S.Diag(SubstDiag->DiagLoc,
- diag::note_type_requirement_substitution_error) << (int)First
- << SubstDiag->SubstitutedEntity << SubstDiag->DiagMessage;
+ S.Diag(SubstDiag->DiagLoc, diag::note_type_requirement_substitution_error)
+ << (int)First << SubstDiag->SubstitutedEntity
+ << SubstDiag->DiagMessage;
else
S.Diag(SubstDiag->DiagLoc,
diag::note_type_requirement_unknown_substitution_error)
@@ -1319,7 +1321,7 @@ static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S,
BO->getRHS()->EvaluateAsInt(SimplifiedRHS, S.Context,
Expr::SE_NoSideEffects,
/*InConstantContext=*/true);
- if (!SimplifiedLHS.Diag && ! SimplifiedRHS.Diag) {
+ if (!SimplifiedLHS.Diag && !SimplifiedRHS.Diag) {
S.Diag(SubstExpr->getBeginLoc(),
diag::note_atomic_constraint_evaluated_to_false_elaborated)
<< (int)First << SubstExpr
@@ -1339,7 +1341,7 @@ static void diagnoseWellFormedUnsatisfiedConstraintExpr(Sema &S,
S.Diag(
CSE->getSourceRange().getBegin(),
diag::
- note_single_arg_concept_specialization_constraint_evaluated_to_false)
+ note_single_arg_concept_specialization_constraint_evaluated_to_false)
<< (int)First
<< CSE->getTemplateArgsAsWritten()->arguments()[0].getArgument()
<< CSE->getNamedConcept();
@@ -1392,9 +1394,8 @@ static void diagnoseUnsatisfiedConstraintExpr(
diagnoseWellFormedUnsatisfiedConstraintExpr(S, cast<Expr *>(Record), First);
}
-void
-Sema::DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction,
- bool First) {
+void Sema::DiagnoseUnsatisfiedConstraint(
+ const ConstraintSatisfaction &Satisfaction, bool First) {
assert(!Satisfaction.IsSatisfied &&
"Attempted to diagnose a satisfied constraint");
for (auto &Record : Satisfaction.Details) {
@@ -1404,8 +1405,7 @@ Sema::DiagnoseUnsatisfiedConstraint(const ConstraintSatisfaction& Satisfaction,
}
void Sema::DiagnoseUnsatisfiedConstraint(
- const ASTConstraintSatisfaction &Satisfaction,
- bool First) {
+ const ASTConstraintSatisfaction &Satisfaction, bool First) {
assert(!Satisfaction.IsSatisfied &&
"Attempted to diagnose a satisfied constraint");
for (auto &Record : Satisfaction) {
@@ -1430,8 +1430,8 @@ const NormalizedConstraint *Sema::getNormalizedAssociatedConstraints(
NormalizationCache
.try_emplace(ConstrainedDecl,
Normalized
- ? new (Context) NormalizedConstraint(
- std::move(*Normalized))
+ ? new (Context)
+ NormalizedConstraint(std::move(*Normalized))
: nullptr)
.first;
}
@@ -1492,7 +1492,7 @@ substituteParameterMappings(Sema &S, NormalizedConstraint &N,
ArgsAsWritten->NumTemplateArgs > I
? ArgsAsWritten->arguments()[I].getLocation()
: SourceLocation()));
- Atomic.ParameterMapping.emplace(TempArgs, OccurringIndices.count());
+ Atomic.ParameterMapping.emplace(TempArgs, OccurringIndices.count());
}
SourceLocation InstLocBegin =
ArgsAsWritten->arguments().empty()
@@ -1538,7 +1538,7 @@ NormalizedConstraint::NormalizedConstraint(ASTContext &C,
NormalizedConstraint RHS,
CompoundConstraintKind Kind)
: Constraint{CompoundConstraint{
- new(C) NormalizedConstraintPair{std::move(LHS), std::move(RHS)},
+ new (C) NormalizedConstraintPair{std::move(LHS), std::move(RHS)},
Kind}} {}
NormalizedConstraint::NormalizedConstraint(ASTContext &C,
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 2bf1511c5..86af11749 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4850,13 +4850,10 @@ void Sema::diagnoseMissingTemplateArguments(const CXXScopeSpec &SS,
diagnoseMissingTemplateArguments(Name, Loc);
}
-ExprResult
-Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &ConceptNameInfo,
- NamedDecl *FoundDecl,
- ConceptDecl *NamedConcept,
- const TemplateArgumentListInfo *TemplateArgs) {
+ExprResult Sema::CheckConceptTemplateId(
+ const CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
+ const DeclarationNameInfo &ConceptNameInfo, NamedDecl *FoundDecl,
+ ConceptDecl *NamedConcept, const TemplateArgumentListInfo *TemplateArgs) {
assert(NamedConcept && "A concept template id without a template?");
if (NamedConcept->isInvalidDecl())
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index f6ee7452c..421fcf5d6 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -6677,9 +6677,8 @@ struct MarkUsedTemplateParameterVisitor : DynamicRecursiveASTVisitor {
llvm::SmallBitVector &Used;
unsigned Depth;
- MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &Used,
- unsigned Depth)
- : Used(Used), Depth(Depth) { }
+ MarkUsedTemplateParameterVisitor(llvm::SmallBitVector &Used, unsigned Depth)
+ : Used(Used), Depth(Depth) {}
bool VisitTemplateTypeParmType(TemplateTypeParmType *T) override {
if (T->getDepth() == Depth)
@@ -7044,9 +7043,9 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
case Type::UnaryTransform:
if (!OnlyDeduced)
- MarkUsedTemplateParameters(Ctx,
- cast<UnaryTransformType>(T)->getUnderlyingType(),
- OnlyDeduced, Depth, Used);
+ MarkUsedTemplateParameters(
+ Ctx, cast<UnaryTransformType>(T)->getUnderlyingType(), OnlyDeduced,
+ Depth, Used);
break;
case Type::PackExpansion:
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index f1c9c5c86..b68a6d123 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1375,543 +1375,541 @@ std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
// Template Instantiation for Types
//===----------------------------------------------------------------------===/
namespace {
- class TemplateInstantiator : public TreeTransform<TemplateInstantiator> {
- const MultiLevelTemplateArgumentList &TemplateArgs;
- SourceLocation Loc;
- DeclarationName Entity;
- // Whether to evaluate the C++20 constraints or simply substitute into them.
- bool EvaluateConstraints = true;
- // Whether Substitution was Incomplete, that is, we tried to substitute in
- // any user provided template arguments which were null.
- bool IsIncomplete = false;
- // Whether an incomplete substituion should be treated as an error.
- bool BailOutOnIncomplete;
-
- private:
- // CWG2770: Function parameters should be instantiated when they are
- // needed by a satisfaction check of an atomic constraint or
- // (recursively) by another function parameter.
- bool maybeInstantiateFunctionParameterToScope(ParmVarDecl *OldParm);
-
- public:
- typedef TreeTransform<TemplateInstantiator> inherited;
-
- TemplateInstantiator(Sema &SemaRef,
- const MultiLevelTemplateArgumentList &TemplateArgs,
- SourceLocation Loc, DeclarationName Entity,
- bool BailOutOnIncomplete = false)
- : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),
- Entity(Entity), BailOutOnIncomplete(BailOutOnIncomplete) {}
-
- void setEvaluateConstraints(bool B) {
- EvaluateConstraints = B;
- }
- bool getEvaluateConstraints() {
- return EvaluateConstraints;
- }
-
- /// Determine whether the given type \p T has already been
- /// transformed.
- ///
- /// For the purposes of template instantiation, a type has already been
- /// transformed if it is NULL or if it is not dependent.
- bool AlreadyTransformed(QualType T);
+class TemplateInstantiator : public TreeTransform<TemplateInstantiator> {
+ const MultiLevelTemplateArgumentList &TemplateArgs;
+ SourceLocation Loc;
+ DeclarationName Entity;
+ // Whether to evaluate the C++20 constraints or simply substitute into them.
+ bool EvaluateConstraints = true;
+ // Whether Substitution was Incomplete, that is, we tried to substitute in
+ // any user provided template arguments which were null.
+ bool IsIncomplete = false;
+ // Whether an incomplete substituion should be treated as an error.
+ bool BailOutOnIncomplete;
+
+private:
+ // CWG2770: Function parameters should be instantiated when they are
+ // needed by a satisfaction check of an atomic constraint or
+ // (recursively) by another function parameter.
+ bool maybeInstantiateFunctionParameterToScope(ParmVarDecl *OldParm);
+
+public:
+ typedef TreeTransform<TemplateInstantiator> inherited;
+
+ TemplateInstantiator(Sema &SemaRef,
+ const MultiLevelTemplateArgumentList &TemplateArgs,
+ SourceLocation Loc, DeclarationName Entity,
+ bool BailOutOnIncomplete = false)
+ : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),
+ Entity(Entity), BailOutOnIncomplete(BailOutOnIncomplete) {}
+
+ void setEvaluateConstraints(bool B) { EvaluateConstraints = B; }
+ bool getEvaluateConstraints() { return EvaluateConstraints; }
+
+ /// Determine whether the given type \p T has already been
+ /// transformed.
+ ///
+ /// For the purposes of template instantiation, a type has already been
+ /// transformed if it is NULL or if it is not dependent.
+ bool AlreadyTransformed(QualType T);
+
+ /// Returns the location of the entity being instantiated, if known.
+ SourceLocation getBaseLocation() { return Loc; }
+
+ /// Returns the name of the entity being instantiated, if any.
+ DeclarationName getBaseEntity() { return Entity; }
+
+ /// Returns whether any substitution so far was incomplete.
+ bool getIsIncomplete() const { return IsIncomplete; }
+
+ /// Sets the "base" location and entity when that
+ /// information is known based on another transformation.
+ void setBase(SourceLocation Loc, DeclarationName Entity) {
+ this->Loc = Loc;
+ this->Entity = Entity;
+ }
- /// Returns the location of the entity being instantiated, if known.
- SourceLocation getBaseLocation() { return Loc; }
+ unsigned TransformTemplateDepth(unsigned Depth) {
+ return TemplateArgs.getNewDepth(Depth);
+ }
- /// Returns the name of the entity being instantiated, if any.
- DeclarationName getBaseEntity() { return Entity; }
+ bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
+ SourceRange PatternRange,
+ ArrayRef<UnexpandedParameterPack> Unexpanded,
+ bool FailOnPackProducingTemplates,
+ bool &ShouldExpand, bool &RetainExpansion,
+ UnsignedOrNone &NumExpansions) {
+ if (SemaRef.CurrentInstantiationScope &&
+ SemaRef.inConstraintSubstitution()) {
+ for (UnexpandedParameterPack ParmPack : Unexpanded) {
+ NamedDecl *VD = ParmPack.first.dyn_cast<NamedDecl *>();
+ if (auto *PVD = dyn_cast_if_present<ParmVarDecl>(VD);
+ PVD && maybeInstantiateFunctionParameterToScope(PVD))
+ return true;
+ }
+ }
- /// Returns whether any substitution so far was incomplete.
- bool getIsIncomplete() const { return IsIncomplete; }
+ return getSema().CheckParameterPacksForExpansion(
+ EllipsisLoc, PatternRange, Unexpanded, TemplateArgs,
+ FailOnPackProducingTemplates, ShouldExpand, RetainExpansion,
+ NumExpansions);
+ }
- /// Sets the "base" location and entity when that
- /// information is known based on another transformation.
- void setBase(SourceLocation Loc, DeclarationName Entity) {
- this->Loc = Loc;
- this->Entity = Entity;
- }
+ void ExpandingFunctionParameterPack(ParmVarDecl *Pack) {
+ SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Pack);
+ }
- unsigned TransformTemplateDepth(unsigned Depth) {
- return TemplateArgs.getNewDepth(Depth);
+ TemplateArgument ForgetPartiallySubstitutedPack() {
+ TemplateArgument Result;
+ if (NamedDecl *PartialPack =
+ SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()) {
+ MultiLevelTemplateArgumentList &TemplateArgs =
+ const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
+ unsigned Depth, Index;
+ std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
+ if (TemplateArgs.hasTemplateArgument(Depth, Index)) {
+ Result = TemplateArgs(Depth, Index);
+ TemplateArgs.setArgument(Depth, Index, TemplateArgument());
+ } else {
+ IsIncomplete = true;
+ if (BailOutOnIncomplete)
+ return TemplateArgument();
+ }
}
- bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
- SourceRange PatternRange,
- ArrayRef<UnexpandedParameterPack> Unexpanded,
- bool FailOnPackProducingTemplates,
- bool &ShouldExpand, bool &RetainExpansion,
- UnsignedOrNone &NumExpansions) {
- if (SemaRef.CurrentInstantiationScope &&
- SemaRef.inConstraintSubstitution()) {
- for (UnexpandedParameterPack ParmPack : Unexpanded) {
- NamedDecl *VD = ParmPack.first.dyn_cast<NamedDecl *>();
- if (auto *PVD = dyn_cast_if_present<ParmVarDecl>(VD);
- PVD && maybeInstantiateFunctionParameterToScope(PVD))
- return true;
- }
- }
+ return Result;
+ }
- return getSema().CheckParameterPacksForExpansion(
- EllipsisLoc, PatternRange, Unexpanded, TemplateArgs,
- FailOnPackProducingTemplates, ShouldExpand, RetainExpansion,
- NumExpansions);
- }
+ void RememberPartiallySubstitutedPack(TemplateArgument Arg) {
+ if (Arg.isNull())
+ return;
- void ExpandingFunctionParameterPack(ParmVarDecl *Pack) {
- SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Pack);
+ if (NamedDecl *PartialPack =
+ SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()) {
+ MultiLevelTemplateArgumentList &TemplateArgs =
+ const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
+ unsigned Depth, Index;
+ std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
+ TemplateArgs.setArgument(Depth, Index, Arg);
}
+ }
- TemplateArgument ForgetPartiallySubstitutedPack() {
- TemplateArgument Result;
- if (NamedDecl *PartialPack
- = SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()){
- MultiLevelTemplateArgumentList &TemplateArgs
- = const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
- unsigned Depth, Index;
- std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
- if (TemplateArgs.hasTemplateArgument(Depth, Index)) {
- Result = TemplateArgs(Depth, Index);
- TemplateArgs.setArgument(Depth, Index, TemplateArgument());
- } else {
- IsIncomplete = true;
- if (BailOutOnIncomplete)
- return TemplateArgument();
- }
- }
+ MultiLevelTemplateArgumentList ForgetSubstitution() {
+ MultiLevelTemplateArgumentList New;
+ New.addOuterRetainedLevels(this->TemplateArgs.getNumLevels());
- return Result;
- }
+ MultiLevelTemplateArgumentList Old =
+ const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
+ const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs) =
+ std::move(New);
+ return Old;
+ }
+ void RememberSubstitution(MultiLevelTemplateArgumentList Old) {
+ const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs) =
+ std::move(Old);
+ }
- void RememberPartiallySubstitutedPack(TemplateArgument Arg) {
- if (Arg.isNull())
- return;
-
- if (NamedDecl *PartialPack
- = SemaRef.CurrentInstantiationScope->getPartiallySubstitutedPack()){
- MultiLevelTemplateArgumentList &TemplateArgs
- = const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
- unsigned Depth, Index;
- std::tie(Depth, Index) = getDepthAndIndex(PartialPack);
- TemplateArgs.setArgument(Depth, Index, Arg);
- }
- }
+ TemplateArgument
+ getTemplateArgumentPackPatternForRewrite(const TemplateArgument &TA) {
+ if (TA.getKind() != TemplateArgument::Pack)
+ return TA;
+ if (SemaRef.ArgPackSubstIndex)
+ return SemaRef.getPackSubstitutedTemplateArgument(TA);
+ assert(TA.pack_size() == 1 && TA.pack_begin()->isPackExpansion() &&
+ "unexpected pack arguments in template rewrite");
+ TemplateArgument Arg = *TA.pack_begin();
+ if (Arg.isPackExpansion())
+ Arg = Arg.getPackExpansionPattern();
+ return Arg;
+ }
- MultiLevelTemplateArgumentList ForgetSubstitution() {
- MultiLevelTemplateArgumentList New;
- New.addOuterRetainedLevels(this->TemplateArgs.getNumLevels());
+ /// Transform the given declaration by instantiating a reference to
+ /// this declaration.
+ Decl *TransformDecl(SourceLocation Loc, Decl *D);
- MultiLevelTemplateArgumentList Old =
- const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs);
- const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs) =
- std::move(New);
- return Old;
- }
- void RememberSubstitution(MultiLevelTemplateArgumentList Old) {
- const_cast<MultiLevelTemplateArgumentList &>(this->TemplateArgs) =
- std::move(Old);
- }
+ void transformAttrs(Decl *Old, Decl *New) {
+ SemaRef.InstantiateAttrs(TemplateArgs, Old, New);
+ }
- TemplateArgument
- getTemplateArgumentPackPatternForRewrite(const TemplateArgument &TA) {
- if (TA.getKind() != TemplateArgument::Pack)
- return TA;
- if (SemaRef.ArgPackSubstIndex)
- return SemaRef.getPackSubstitutedTemplateArgument(TA);
- assert(TA.pack_size() == 1 && TA.pack_begin()->isPackExpansion() &&
- "unexpected pack arguments in template rewrite");
- TemplateArgument Arg = *TA.pack_begin();
- if (Arg.isPackExpansion())
- Arg = Arg.getPackExpansionPattern();
- return Arg;
+ void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> NewDecls) {
+ if (Old->isParameterPack() &&
+ (NewDecls.size() != 1 || !NewDecls.front()->isParameterPack())) {
+ SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Old);
+ for (auto *New : NewDecls)
+ SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(
+ Old, cast<VarDecl>(New));
+ return;
}
- /// Transform the given declaration by instantiating a reference to
- /// this declaration.
- Decl *TransformDecl(SourceLocation Loc, Decl *D);
-
- void transformAttrs(Decl *Old, Decl *New) {
- SemaRef.InstantiateAttrs(TemplateArgs, Old, New);
+ assert(NewDecls.size() == 1 &&
+ "should only have multiple expansions for a pack");
+ Decl *New = NewDecls.front();
+
+ // If we've instantiated the call operator of a lambda or the call
+ // operator template of a generic lambda, update the "instantiation of"
+ // information.
+ auto *NewMD = dyn_cast<CXXMethodDecl>(New);
+ if (NewMD && isLambdaCallOperator(NewMD)) {
+ auto *OldMD = dyn_cast<CXXMethodDecl>(Old);
+ if (auto *NewTD = NewMD->getDescribedFunctionTemplate())
+ NewTD->setInstantiatedFromMemberTemplate(
+ OldMD->getDescribedFunctionTemplate());
+ else
+ NewMD->setInstantiationOfMemberFunction(OldMD,
+ TSK_ImplicitInstantiation);
}
- void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> NewDecls) {
- if (Old->isParameterPack() &&
- (NewDecls.size() != 1 || !NewDecls.front()->isParameterPack())) {
- SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack(Old);
- for (auto *New : NewDecls)
- SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(
- Old, cast<VarDecl>(New));
- return;
- }
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(Old, New);
- assert(NewDecls.size() == 1 &&
- "should only have multiple expansions for a pack");
- Decl *New = NewDecls.front();
-
- // If we've instantiated the call operator of a lambda or the call
- // operator template of a generic lambda, update the "instantiation of"
- // information.
- auto *NewMD = dyn_cast<CXXMethodDecl>(New);
- if (NewMD && isLambdaCallOperator(NewMD)) {
- auto *OldMD = dyn_cast<CXXMethodDecl>(Old);
- if (auto *NewTD = NewMD->getDescribedFunctionTemplate())
- NewTD->setInstantiatedFromMemberTemplate(
- OldMD->getDescribedFunctionTemplate());
- else
- NewMD->setInstantiationOfMemberFunction(OldMD,
- TSK_ImplicitInstantiation);
- }
+ // We recreated a local declaration, but not by instantiating it. There
+ // may be pending dependent diagnostics to produce.
+ if (auto *DC = dyn_cast<DeclContext>(Old);
+ DC && DC->isDependentContext() && DC->isFunctionOrMethod())
+ SemaRef.PerformDependentDiagnostics(DC, TemplateArgs);
+ }
- SemaRef.CurrentInstantiationScope->InstantiatedLocal(Old, New);
+ /// Transform the definition of the given declaration by
+ /// instantiating it.
+ Decl *TransformDefinition(SourceLocation Loc, Decl *D);
- // We recreated a local declaration, but not by instantiating it. There
- // may be pending dependent diagnostics to produce.
- if (auto *DC = dyn_cast<DeclContext>(Old);
- DC && DC->isDependentContext() && DC->isFunctionOrMethod())
- SemaRef.PerformDependentDiagnostics(DC, TemplateArgs);
- }
+ /// Transform the first qualifier within a scope by instantiating the
+ /// declaration.
+ NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc);
- /// Transform the definition of the given declaration by
- /// instantiating it.
- Decl *TransformDefinition(SourceLocation Loc, Decl *D);
-
- /// Transform the first qualifier within a scope by instantiating the
- /// declaration.
- NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc);
-
- bool TransformExceptionSpec(SourceLocation Loc,
- FunctionProtoType::ExceptionSpecInfo &ESI,
- SmallVectorImpl<QualType> &Exceptions,
- bool &Changed);
-
- /// Rebuild the exception declaration and register the declaration
- /// as an instantiated local.
- VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
- TypeSourceInfo *Declarator,
- SourceLocation StartLoc,
- SourceLocation NameLoc,
- IdentifierInfo *Name);
-
- /// Rebuild the Objective-C exception declaration and register the
- /// declaration as an instantiated local.
- VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
- TypeSourceInfo *TSInfo, QualType T);
-
- TemplateName
- TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc,
- SourceLocation TemplateKWLoc, TemplateName Name,
- SourceLocation NameLoc,
- QualType ObjectType = QualType(),
- NamedDecl *FirstQualifierInScope = nullptr,
- bool AllowInjectedClassName = false);
-
- const AnnotateAttr *TransformAnnotateAttr(const AnnotateAttr *AA);
- const CXXAssumeAttr *TransformCXXAssumeAttr(const CXXAssumeAttr *AA);
- const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH);
- const NoInlineAttr *TransformStmtNoInlineAttr(const Stmt *OrigS,
- const Stmt *InstS,
- const NoInlineAttr *A);
- const AlwaysInlineAttr *
- TransformStmtAlwaysInlineAttr(const Stmt *OrigS, const Stmt *InstS,
- const AlwaysInlineAttr *A);
- const CodeAlignAttr *TransformCodeAlignAttr(const CodeAlignAttr *CA);
- const OpenACCRoutineDeclAttr *
- TransformOpenACCRoutineDeclAttr(const OpenACCRoutineDeclAttr *A);
- ExprResult TransformPredefinedExpr(PredefinedExpr *E);
- ExprResult TransformDeclRefExpr(DeclRefExpr *E);
- ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
-
- ExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
- NonTypeTemplateParmDecl *D);
-
- /// Rebuild a DeclRefExpr for a VarDecl reference.
- ExprResult RebuildVarDeclRefExpr(ValueDecl *PD, SourceLocation Loc);
-
- /// Transform a reference to a function or init-capture parameter pack.
- ExprResult TransformFunctionParmPackRefExpr(DeclRefExpr *E, ValueDecl *PD);
-
- /// Transform a FunctionParmPackExpr which was built when we couldn't
- /// expand a function parameter pack reference which refers to an expanded
- /// pack.
- ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);
-
- QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
- FunctionProtoTypeLoc TL) {
- // Call the base version; it will forward to our overridden version below.
- return inherited::TransformFunctionProtoType(TLB, TL);
- }
+ bool TransformExceptionSpec(SourceLocation Loc,
+ FunctionProtoType::ExceptionSpecInfo &ESI,
+ SmallVectorImpl<QualType> &Exceptions,
+ bool &Changed);
+
+ /// Rebuild the exception declaration and register the declaration
+ /// as an instantiated local.
+ VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
+ TypeSourceInfo *Declarator,
+ SourceLocation StartLoc, SourceLocation NameLoc,
+ IdentifierInfo *Name);
+
+ /// Rebuild the Objective-C exception declaration and register the
+ /// declaration as an instantiated local.
+ VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
+ TypeSourceInfo *TSInfo, QualType T);
+
+ TemplateName TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc,
+ SourceLocation TemplateKWLoc,
+ TemplateName Name, SourceLocation NameLoc,
+ QualType ObjectType = QualType(),
+ NamedDecl *FirstQualifierInScope = nullptr,
+ bool AllowInjectedClassName = false);
+
+ const AnnotateAttr *TransformAnnotateAttr(const AnnotateAttr *AA);
+ const CXXAssumeAttr *TransformCXXAssumeAttr(const CXXAssumeAttr *AA);
+ const LoopHintAttr *TransformLoopHintAttr(const LoopHintAttr *LH);
+ const NoInlineAttr *TransformStmtNoInlineAttr(const Stmt *OrigS,
+ const Stmt *InstS,
+ const NoInlineAttr *A);
+ const AlwaysInlineAttr *
+ TransformStmtAlwaysInlineAttr(const Stmt *OrigS, const Stmt *InstS,
+ const AlwaysInlineAttr *A);
+ const CodeAlignAttr *TransformCodeAlignAttr(const CodeAlignAttr *CA);
+ const OpenACCRoutineDeclAttr *
+ TransformOpenACCRoutineDeclAttr(const OpenACCRoutineDeclAttr *A);
+ ExprResult TransformPredefinedExpr(PredefinedExpr *E);
+ ExprResult TransformDeclRefExpr(DeclRefExpr *E);
+ ExprResult TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E);
+
+ ExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
+ NonTypeTemplateParmDecl *D);
+
+ /// Rebuild a DeclRefExpr for a VarDecl reference.
+ ExprResult RebuildVarDeclRefExpr(ValueDecl *PD, SourceLocation Loc);
+
+ /// Transform a reference to a function or init-capture parameter pack.
+ ExprResult TransformFunctionParmPackRefExpr(DeclRefExpr *E, ValueDecl *PD);
+
+ /// Transform a FunctionParmPackExpr which was built when we couldn't
+ /// expand a function parameter pack reference which refers to an expanded
+ /// pack.
+ ExprResult TransformFunctionParmPackExpr(FunctionParmPackExpr *E);
+
+ QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
+ FunctionProtoTypeLoc TL) {
+ // Call the base version; it will forward to our overridden version below.
+ return inherited::TransformFunctionProtoType(TLB, TL);
+ }
- QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL) {
- auto Type = inherited::TransformTagType(TLB, TL);
- if (!Type.isNull())
- return Type;
- // Special case for transforming a deduction guide, we return a
- // transformed TemplateSpecializationType.
- // FIXME: Why is this hack necessary?
- if (const auto *ICNT = dyn_cast<InjectedClassNameType>(TL.getTypePtr());
- ICNT && SemaRef.CodeSynthesisContexts.back().Kind ==
- Sema::CodeSynthesisContext::BuildingDeductionGuides) {
- Type = inherited::TransformType(
- ICNT->getOriginalDecl()->getCanonicalTemplateSpecializationType(
- SemaRef.Context));
- TLB.pushTrivial(SemaRef.Context, Type, TL.getNameLoc());
- }
+ QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL) {
+ auto Type = inherited::TransformTagType(TLB, TL);
+ if (!Type.isNull())
return Type;
+ // Special case for transforming a deduction guide, we return a
+ // transformed TemplateSpecializationType.
+ // FIXME: Why is this hack necessary?
+ if (const auto *ICNT = dyn_cast<InjectedClassNameType>(TL.getTypePtr());
+ ICNT && SemaRef.CodeSynthesisContexts.back().Kind ==
+ Sema::CodeSynthesisContext::BuildingDeductionGuides) {
+ Type = inherited::TransformType(
+ ICNT->getOriginalDecl()->getCanonicalTemplateSpecializationType(
+ SemaRef.Context));
+ TLB.pushTrivial(SemaRef.Context, Type, TL.getNameLoc());
}
- // Override the default version to handle a rewrite-template-arg-pack case
- // for building a deduction guide.
- bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
- TemplateArgumentLoc &Output,
- bool Uneval = false) {
- const TemplateArgument &Arg = Input.getArgument();
- std::vector<TemplateArgument> TArgs;
- switch (Arg.getKind()) {
- case TemplateArgument::Pack:
- assert(SemaRef.CodeSynthesisContexts.empty() ||
- SemaRef.CodeSynthesisContexts.back().Kind ==
- Sema::CodeSynthesisContext::BuildingDeductionGuides);
- // Literally rewrite the template argument pack, instead of unpacking
- // it.
- for (auto &pack : Arg.getPackAsArray()) {
- TemplateArgumentLoc Input = SemaRef.getTrivialTemplateArgumentLoc(
- pack, QualType(), SourceLocation{});
- TemplateArgumentLoc Output;
- if (TransformTemplateArgument(Input, Output, Uneval))
- return true; // fails
- TArgs.push_back(Output.getArgument());
- }
- Output = SemaRef.getTrivialTemplateArgumentLoc(
- TemplateArgument(llvm::ArrayRef(TArgs).copy(SemaRef.Context)),
- QualType(), SourceLocation{});
- return false;
- default:
- break;
+ return Type;
+ }
+ // Override the default version to handle a rewrite-template-arg-pack case
+ // for building a deduction guide.
+ bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
+ TemplateArgumentLoc &Output,
+ bool Uneval = false) {
+ const TemplateArgument &Arg = Input.getArgument();
+ std::vector<TemplateArgument> TArgs;
+ switch (Arg.getKind()) {
+ case TemplateArgument::Pack:
+ assert(SemaRef.CodeSynthesisContexts.empty() ||
+ SemaRef.CodeSynthesisContexts.back().Kind ==
+ Sema::CodeSynthesisContext::BuildingDeductionGuides);
+ // Literally rewrite the template argument pack, instead of unpacking
+ // it.
+ for (auto &pack : Arg.getPackAsArray()) {
+ TemplateArgumentLoc Input = SemaRef.getTrivialTemplateArgumentLoc(
+ pack, QualType(), SourceLocation{});
+ TemplateArgumentLoc Output;
+ if (TransformTemplateArgument(Input, Output, Uneval))
+ return true; // fails
+ TArgs.push_back(Output.getArgument());
}
- return inherited::TransformTemplateArgument(Input, Output, Uneval);
+ Output = SemaRef.getTrivialTemplateArgumentLoc(
+ TemplateArgument(llvm::ArrayRef(TArgs).copy(SemaRef.Context)),
+ QualType(), SourceLocation{});
+ return false;
+ default:
+ break;
}
+ return inherited::TransformTemplateArgument(Input, Output, Uneval);
+ }
- using TreeTransform::TransformTemplateSpecializationType;
- QualType
- TransformTemplateSpecializationType(TypeLocBuilder &TLB,
- TemplateSpecializationTypeLoc TL) {
- auto *T = TL.getTypePtr();
- if (!getSema().ArgPackSubstIndex || !T->isSugared() ||
- !isPackProducingBuiltinTemplateName(T->getTemplateName()))
- return TreeTransform::TransformTemplateSpecializationType(TLB, TL);
- // Look through sugar to get to the SubstBuiltinTemplatePackType that we
- // need to substitute into.
-
- // `TransformType` code below will handle picking the element from a pack
- // with the index `ArgPackSubstIndex`.
- // FIXME: add ability to represent sugarred type for N-th element of a
- // builtin pack and produce the sugar here.
- QualType R = TransformType(T->desugar());
- TLB.pushTrivial(getSema().getASTContext(), R, TL.getBeginLoc());
- return R;
- }
+ using TreeTransform::TransformTemplateSpecializationType;
+ QualType
+ TransformTemplateSpecializationType(TypeLocBuilder &TLB,
+ TemplateSpecializationTypeLoc TL) {
+ auto *T = TL.getTypePtr();
+ if (!getSema().ArgPackSubstIndex || !T->isSugared() ||
+ !isPackProducingBuiltinTemplateName(T->getTemplateName()))
+ return TreeTransform::TransformTemplateSpecializationType(TLB, TL);
+ // Look through sugar to get to the SubstBuiltinTemplatePackType that we
+ // need to substitute into.
+
+ // `TransformType` code below will handle picking the element from a pack
+ // with the index `ArgPackSubstIndex`.
+ // FIXME: add ability to represent sugarred type for N-th element of a
+ // builtin pack and produce the sugar here.
+ QualType R = TransformType(T->desugar());
+ TLB.pushTrivial(getSema().getASTContext(), R, TL.getBeginLoc());
+ return R;
+ }
- UnsignedOrNone ComputeSizeOfPackExprWithoutSubstitution(
- ArrayRef<TemplateArgument> PackArgs) {
- // Don't do this when rewriting template parameters for CTAD:
- // 1) The heuristic needs the unpacked Subst* nodes to figure out the
- // expanded size, but this never applies since Subst* nodes are not
- // created in rewrite scenarios.
- //
- // 2) The heuristic substitutes into the pattern with pack expansion
- // suppressed, which does not meet the requirements for argument
- // rewriting when template arguments include a non-pack matching against
- // a pack, particularly when rewriting an alias CTAD.
- if (TemplateArgs.isRewrite())
- return std::nullopt;
-
- return inherited::ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
- }
+ UnsignedOrNone ComputeSizeOfPackExprWithoutSubstitution(
+ ArrayRef<TemplateArgument> PackArgs) {
+ // Don't do this when rewriting template parameters for CTAD:
+ // 1) The heuristic needs the unpacked Subst* nodes to figure out the
+ // expanded size, but this never applies since Subst* nodes are not
+ // created in rewrite scenarios.
+ //
+ // 2) The heuristic substitutes into the pattern with pack expansion
+ // suppressed, which does not meet the requirements for argument
+ // rewriting when template arguments include a non-pack matching against
+ // a pack, particularly when rewriting an alias CTAD.
+ if (TemplateArgs.isRewrite())
+ return std::nullopt;
- template<typename Fn>
- QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
- FunctionProtoTypeLoc TL,
- CXXRecordDecl *ThisContext,
- Qualifiers ThisTypeQuals,
- Fn TransformExceptionSpec);
-
- ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
- int indexAdjustment,
- UnsignedOrNone NumExpansions,
- bool ExpectParameterPack);
-
- using inherited::TransformTemplateTypeParmType;
- /// Transforms a template type parameter type by performing
- /// substitution of the corresponding template type argument.
- QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
- TemplateTypeParmTypeLoc TL,
- bool SuppressObjCLifetime);
-
- QualType BuildSubstTemplateTypeParmType(
- TypeLocBuilder &TLB, bool SuppressObjCLifetime, bool Final,
- Decl *AssociatedDecl, unsigned Index, UnsignedOrNone PackIndex,
- TemplateArgument Arg, SourceLocation NameLoc);
-
- /// Transforms an already-substituted template type parameter pack
- /// into either itself (if we aren't substituting into its pack expansion)
- /// or the appropriate substituted argument.
- using inherited::TransformSubstTemplateTypeParmPackType;
- QualType
- TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
- SubstTemplateTypeParmPackTypeLoc TL,
- bool SuppressObjCLifetime);
- QualType
- TransformSubstBuiltinTemplatePackType(TypeLocBuilder &TLB,
- SubstBuiltinTemplatePackTypeLoc TL);
-
- CXXRecordDecl::LambdaDependencyKind
- ComputeLambdaDependency(LambdaScopeInfo *LSI) {
- if (auto TypeAlias =
- TemplateInstArgsHelpers::getEnclosingTypeAliasTemplateDecl(
- getSema());
- TypeAlias && TemplateInstArgsHelpers::isLambdaEnclosedByTypeAliasDecl(
- LSI->CallOperator, TypeAlias.PrimaryTypeAliasDecl)) {
- unsigned TypeAliasDeclDepth = TypeAlias.Template->getTemplateDepth();
- if (TypeAliasDeclDepth >= TemplateArgs.getNumSubstitutedLevels())
+ return inherited::ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
+ }
+
+ template <typename Fn>
+ QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
+ FunctionProtoTypeLoc TL,
+ CXXRecordDecl *ThisContext,
+ Qualifiers ThisTypeQuals,
+ Fn TransformExceptionSpec);
+
+ ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
+ int indexAdjustment,
+ UnsignedOrNone NumExpansions,
+ bool ExpectParameterPack);
+
+ using inherited::TransformTemplateTypeParmType;
+ /// Transforms a template type parameter type by performing
+ /// substitution of the corresponding template type argument.
+ QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
+ TemplateTypeParmTypeLoc TL,
+ bool SuppressObjCLifetime);
+
+ QualType BuildSubstTemplateTypeParmType(TypeLocBuilder &TLB,
+ bool SuppressObjCLifetime, bool Final,
+ Decl *AssociatedDecl, unsigned Index,
+ UnsignedOrNone PackIndex,
+ TemplateArgument Arg,
+ SourceLocation NameLoc);
+
+ /// Transforms an already-substituted template type parameter pack
+ /// into either itself (if we aren't substituting into its pack expansion)
+ /// or the appropriate substituted argument.
+ using inherited::TransformSubstTemplateTypeParmPackType;
+ QualType
+ TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
+ SubstTemplateTypeParmPackTypeLoc TL,
+ bool SuppressObjCLifetime);
+ QualType
+ TransformSubstBuiltinTemplatePackType(TypeLocBuilder &TLB,
+ SubstBuiltinTemplatePackTypeLoc TL);
+
+ CXXRecordDecl::LambdaDependencyKind
+ ComputeLambdaDependency(LambdaScopeInfo *LSI) {
+ if (auto TypeAlias =
+ TemplateInstArgsHelpers::getEnclosingTypeAliasTemplateDecl(
+ getSema());
+ TypeAlias && TemplateInstArgsHelpers::isLambdaEnclosedByTypeAliasDecl(
+ LSI->CallOperator, TypeAlias.PrimaryTypeAliasDecl)) {
+ unsigned TypeAliasDeclDepth = TypeAlias.Template->getTemplateDepth();
+ if (TypeAliasDeclDepth >= TemplateArgs.getNumSubstitutedLevels())
+ return CXXRecordDecl::LambdaDependencyKind::LDK_AlwaysDependent;
+ for (const TemplateArgument &TA : TypeAlias.AssociatedTemplateArguments)
+ if (TA.isDependent())
return CXXRecordDecl::LambdaDependencyKind::LDK_AlwaysDependent;
- for (const TemplateArgument &TA : TypeAlias.AssociatedTemplateArguments)
- if (TA.isDependent())
- return CXXRecordDecl::LambdaDependencyKind::LDK_AlwaysDependent;
- }
- return inherited::ComputeLambdaDependency(LSI);
}
+ return inherited::ComputeLambdaDependency(LSI);
+ }
- ExprResult TransformLambdaExpr(LambdaExpr *E) {
- // Do not rebuild lambdas to avoid creating a new type.
- // Lambdas have already been processed inside their eval contexts.
- if (SemaRef.RebuildingImmediateInvocation)
- return E;
- LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true,
- /*InstantiatingLambdaOrBlock=*/true);
- Sema::ConstraintEvalRAII<TemplateInstantiator> RAII(*this);
+ ExprResult TransformLambdaExpr(LambdaExpr *E) {
+ // Do not rebuild lambdas to avoid creating a new type.
+ // Lambdas have already been processed inside their eval contexts.
+ if (SemaRef.RebuildingImmediateInvocation)
+ return E;
+ LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true,
+ /*InstantiatingLambdaOrBlock=*/true);
+ Sema::ConstraintEvalRAII<TemplateInstantiator> RAII(*this);
- return inherited::TransformLambdaExpr(E);
- }
+ return inherited::TransformLambdaExpr(E);
+ }
- ExprResult TransformBlockExpr(BlockExpr *E) {
- LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true,
- /*InstantiatingLambdaOrBlock=*/true);
- return inherited::TransformBlockExpr(E);
- }
+ ExprResult TransformBlockExpr(BlockExpr *E) {
+ LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true,
+ /*InstantiatingLambdaOrBlock=*/true);
+ return inherited::TransformBlockExpr(E);
+ }
- ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
- LambdaScopeInfo *LSI) {
- CXXMethodDecl *MD = LSI->CallOperator;
- for (ParmVarDecl *PVD : MD->parameters()) {
- assert(PVD && "null in a parameter list");
- if (!PVD->hasDefaultArg())
- continue;
- Expr *UninstExpr = PVD->getUninstantiatedDefaultArg();
- // FIXME: Obtain the source location for the '=' token.
- SourceLocation EqualLoc = UninstExpr->getBeginLoc();
- if (SemaRef.SubstDefaultArgument(EqualLoc, PVD, TemplateArgs)) {
- // If substitution fails, the default argument is set to a
- // RecoveryExpr that wraps the uninstantiated default argument so
- // that downstream diagnostics are omitted.
- ExprResult ErrorResult = SemaRef.CreateRecoveryExpr(
- UninstExpr->getBeginLoc(), UninstExpr->getEndLoc(), {UninstExpr},
- UninstExpr->getType());
- if (ErrorResult.isUsable())
- PVD->setDefaultArg(ErrorResult.get());
- }
+ ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
+ LambdaScopeInfo *LSI) {
+ CXXMethodDecl *MD = LSI->CallOperator;
+ for (ParmVarDecl *PVD : MD->parameters()) {
+ assert(PVD && "null in a parameter list");
+ if (!PVD->hasDefaultArg())
+ continue;
+ Expr *UninstExpr = PVD->getUninstantiatedDefaultArg();
+ // FIXME: Obtain the source location for the '=' token.
+ SourceLocation EqualLoc = UninstExpr->getBeginLoc();
+ if (SemaRef.SubstDefaultArgument(EqualLoc, PVD, TemplateArgs)) {
+ // If substitution fails, the default argument is set to a
+ // RecoveryExpr that wraps the uninstantiated default argument so
+ // that downstream diagnostics are omitted.
+ ExprResult ErrorResult = SemaRef.CreateRecoveryExpr(
+ UninstExpr->getBeginLoc(), UninstExpr->getEndLoc(), {UninstExpr},
+ UninstExpr->getType());
+ if (ErrorResult.isUsable())
+ PVD->setDefaultArg(ErrorResult.get());
}
- return inherited::RebuildLambdaExpr(StartLoc, EndLoc, LSI);
}
+ return inherited::RebuildLambdaExpr(StartLoc, EndLoc, LSI);
+ }
- StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body) {
- // Currently, we instantiate the body when instantiating the lambda
- // expression. However, `EvaluateConstraints` is disabled during the
- // instantiation of the lambda expression, causing the instantiation
- // failure of the return type requirement in the body. If p0588r1 is fully
- // implemented, the body will be lazily instantiated, and this problem
- // will not occur. Here, `EvaluateConstraints` is temporarily set to
- // `true` to temporarily fix this issue.
- // FIXME: This temporary fix can be removed after fully implementing
- // p0588r1.
- llvm::SaveAndRestore _(EvaluateConstraints, true);
- return inherited::TransformLambdaBody(E, Body);
- }
+ StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body) {
+ // Currently, we instantiate the body when instantiating the lambda
+ // expression. However, `EvaluateConstraints` is disabled during the
+ // instantiation of the lambda expression, causing the instantiation
+ // failure of the return type requirement in the body. If p0588r1 is fully
+ // implemented, the body will be lazily instantiated, and this problem
+ // will not occur. Here, `EvaluateConstraints` is temporarily set to
+ // `true` to temporarily fix this issue.
+ // FIXME: This temporary fix can be removed after fully implementing
+ // p0588r1.
+ llvm::SaveAndRestore _(EvaluateConstraints, true);
+ return inherited::TransformLambdaBody(E, Body);
+ }
- ExprResult TransformRequiresExpr(RequiresExpr *E) {
- LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
- ExprResult TransReq = inherited::TransformRequiresExpr(E);
- if (TransReq.isInvalid())
- return TransReq;
- assert(TransReq.get() != E &&
- "Do not change value of isSatisfied for the existing expression. "
- "Create a new expression instead.");
- if (E->getBody()->isDependentContext()) {
- Sema::SFINAETrap Trap(SemaRef);
- // We recreate the RequiresExpr body, but not by instantiating it.
- // Produce pending diagnostics for dependent access check.
- SemaRef.PerformDependentDiagnostics(E->getBody(), TemplateArgs);
- // FIXME: Store SFINAE diagnostics in RequiresExpr for diagnosis.
- if (Trap.hasErrorOccurred())
- TransReq.getAs<RequiresExpr>()->setSatisfied(false);
- }
+ ExprResult TransformRequiresExpr(RequiresExpr *E) {
+ LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
+ ExprResult TransReq = inherited::TransformRequiresExpr(E);
+ if (TransReq.isInvalid())
return TransReq;
+ assert(TransReq.get() != E &&
+ "Do not change value of isSatisfied for the existing expression. "
+ "Create a new expression instead.");
+ if (E->getBody()->isDependentContext()) {
+ Sema::SFINAETrap Trap(SemaRef);
+ // We recreate the RequiresExpr body, but not by instantiating it.
+ // Produce pending diagnostics for dependent access check.
+ SemaRef.PerformDependentDiagnostics(E->getBody(), TemplateArgs);
+ // FIXME: Store SFINAE diagnostics in RequiresExpr for diagnosis.
+ if (Trap.hasErrorOccurred())
+ TransReq.getAs<RequiresExpr>()->setSatisfied(false);
}
+ return TransReq;
+ }
- bool TransformRequiresExprRequirements(
- ArrayRef<concepts::Requirement *> Reqs,
- SmallVectorImpl<concepts::Requirement *> &Transformed) {
- bool SatisfactionDetermined = false;
- for (concepts::Requirement *Req : Reqs) {
- concepts::Requirement *TransReq = nullptr;
- if (!SatisfactionDetermined) {
- if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
- TransReq = TransformTypeRequirement(TypeReq);
- else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
- TransReq = TransformExprRequirement(ExprReq);
- else
- TransReq = TransformNestedRequirement(
- cast<concepts::NestedRequirement>(Req));
- if (!TransReq)
- return true;
- if (!TransReq->isDependent() && !TransReq->isSatisfied())
- // [expr.prim.req]p6
- // [...] The substitution and semantic constraint checking
- // proceeds in lexical order and stops when a condition that
- // determines the result of the requires-expression is
- // encountered. [..]
- SatisfactionDetermined = true;
- } else
- TransReq = Req;
- Transformed.push_back(TransReq);
- }
- return false;
+ bool TransformRequiresExprRequirements(
+ ArrayRef<concepts::Requirement *> Reqs,
+ SmallVectorImpl<concepts::Requirement *> &Transformed) {
+ bool SatisfactionDetermined = false;
+ for (concepts::Requirement *Req : Reqs) {
+ concepts::Requirement *TransReq = nullptr;
+ if (!SatisfactionDetermined) {
+ if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
+ TransReq = TransformTypeRequirement(TypeReq);
+ else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
+ TransReq = TransformExprRequirement(ExprReq);
+ else
+ TransReq = TransformNestedRequirement(
+ cast<concepts::NestedRequirement>(Req));
+ if (!TransReq)
+ return true;
+ if (!TransReq->isDependent() && !TransReq->isSatisfied())
+ // [expr.prim.req]p6
+ // [...] The substitution and semantic constraint checking
+ // proceeds in lexical order and stops when a condition that
+ // determines the result of the requires-expression is
+ // encountered. [..]
+ SatisfactionDetermined = true;
+ } else
+ TransReq = Req;
+ Transformed.push_back(TransReq);
}
+ return false;
+ }
- TemplateParameterList *TransformTemplateParameterList(
- TemplateParameterList *OrigTPL) {
- if (!OrigTPL || !OrigTPL->size()) return OrigTPL;
-
- DeclContext *Owner = OrigTPL->getParam(0)->getDeclContext();
- TemplateDeclInstantiator DeclInstantiator(getSema(),
- /* DeclContext *Owner */ Owner, TemplateArgs);
- DeclInstantiator.setEvaluateConstraints(EvaluateConstraints);
- return DeclInstantiator.SubstTemplateParams(OrigTPL);
- }
+ TemplateParameterList *
+ TransformTemplateParameterList(TemplateParameterList *OrigTPL) {
+ if (!OrigTPL || !OrigTPL->size())
+ return OrigTPL;
+
+ DeclContext *Owner = OrigTPL->getParam(0)->getDeclContext();
+ TemplateDeclInstantiator DeclInstantiator(getSema(),
+ /* DeclContext *Owner */ Owner,
+ TemplateArgs);
+ DeclInstantiator.setEvaluateConstraints(EvaluateConstraints);
+ return DeclInstantiator.SubstTemplateParams(OrigTPL);
+ }
- concepts::TypeRequirement *
- TransformTypeRequirement(concepts::TypeRequirement *Req);
- concepts::ExprRequirement *
- TransformExprRequirement(concepts::ExprRequirement *Req);
- concepts::NestedRequirement *
- TransformNestedRequirement(concepts::NestedRequirement *Req);
- ExprResult TransformRequiresTypeParams(
- SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
- RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
- SmallVectorImpl<QualType> &PTypes,
- SmallVectorImpl<ParmVarDecl *> &TransParams,
- Sema::ExtParameterInfoBuilder &PInfos);
- };
-}
+ concepts::TypeRequirement *
+ TransformTypeRequirement(concepts::TypeRequirement *Req);
+ concepts::ExprRequirement *
+ TransformExprRequirement(concepts::ExprRequirement *Req);
+ concepts::NestedRequirement *
+ TransformNestedRequirement(concepts::NestedRequirement *Req);
+ ExprResult TransformRequiresTypeParams(
+ SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
+ RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
+ SmallVectorImpl<QualType> &PTypes,
+ SmallVectorImpl<ParmVarDecl *> &TransParams,
+ Sema::ExtParameterInfoBuilder &PInfos);
+};
+} // namespace
bool TemplateInstantiator::AlreadyTransformed(QualType T) {
if (T.isNull())
@@ -2767,8 +2765,8 @@ TemplateInstantiator::TransformNestedRequirement(
Req->getConstraintSatisfaction());
return Req;
}
- Sema::InstantiatingTemplate ReqInst(SemaRef,
- Req->getConstraintExpr()->getBeginLoc(), Req,
+ Sema::InstantiatingTemplate ReqInst(
+ SemaRef, Req->getConstraintExpr()->getBeginLoc(), Req,
Sema::InstantiatingTemplate::ConstraintsCheck{},
Req->getConstraintExpr()->getSourceRange());
if (!getEvaluateConstraints()) {
@@ -2790,8 +2788,8 @@ TemplateInstantiator::TransformNestedRequirement(
EnterExpressionEvaluationContext ContextRAII(
SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
Sema::SFINAETrap Trap(SemaRef);
- Sema::InstantiatingTemplate ConstrInst(SemaRef,
- Req->getConstraintExpr()->getBeginLoc(), Req, Info,
+ Sema::InstantiatingTemplate ConstrInst(
+ SemaRef, Req->getConstraintExpr()->getBeginLoc(), Req, Info,
Req->getConstraintExpr()->getSourceRange());
if (ConstrInst.isInvalid())
return nullptr;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 696730148..ac9511467 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -5109,7 +5109,7 @@ bool TreeTransform<Derived>::TransformTemplateArguments(
// all of the template arguments in the argument pack.
typedef TemplateArgumentLocInventIterator<Derived,
TemplateArgument::pack_iterator>
- PackLocIterator;
+ PackLocIterator;
if (TransformTemplateArguments(
PackLocIterator(*this, In.getArgument().pack_begin()),
PackLocIterator(*this, In.getArgument().pack_end()), Outputs,
@@ -5179,7 +5179,6 @@ bool TreeTransform<Derived>::TransformTemplateArguments(
}
return false;
-
}
// FIXME: Find ways to reduce code duplication for pack expansions.
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 70b898a53..1c3999d69 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -807,7 +807,7 @@ readConstraintSatisfaction(ASTRecordReader &Record) {
if (!Satisfaction.IsSatisfied) {
unsigned NumDetailRecords = Record.readInt();
for (unsigned i = 0; i != NumDetailRecords; ++i) {
- if (/* IsDiagnostic */Record.readInt()) {
+ if (/* IsDiagnostic */ Record.readInt()) {
SourceLocation DiagLocation = Record.readSourceLocation();
StringRef DiagMessage = C.backupStr(Record.readString());
``````````
</details>
https://github.com/llvm/llvm-project/pull/161669
More information about the libcxx-commits
mailing list