[clang] [clang][ASTImporter] Import C++20 concepts related nodes (PR #104731)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 18 18:50:14 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Ding Fei (danix800)
<details>
<summary>Changes</summary>
Related nodes including:
- ConceptDecl
- RequiresExprBodyDecl
- ImplicitConceptSpecializationDecl
- RequiresExpr
- ConceptSpecializationExpr
- concepts::Requirement
- concepts::ExprRequirement
- concepts::NestedRequirement
- concepts::TypeRequirement
- concepts::Requirement::ReturnTypeRequirement
- concepts::Requirement::SubstitutionDiagnostic
---
Patch is 27.21 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/104731.diff
5 Files Affected:
- (modified) clang/include/clang/AST/ExprConcepts.h (+31-1)
- (modified) clang/lib/AST/ASTImporter.cpp (+265)
- (modified) clang/lib/AST/ExprConcepts.cpp (+98-8)
- (modified) clang/lib/Sema/SemaConcept.cpp (-58)
- (modified) clang/unittests/AST/ASTImporterTest.cpp (+43)
``````````diff
diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h
index 29913fd84c58b4..7c8972c0ced0bb 100644
--- a/clang/include/clang/AST/ExprConcepts.h
+++ b/clang/include/clang/AST/ExprConcepts.h
@@ -59,11 +59,21 @@ class ConceptSpecializationExpr final : public Expr {
ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction);
+ ConceptSpecializationExpr(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
+ ASTConstraintSatisfaction *Satisfaction);
+
ConceptSpecializationExpr(const ASTContext &C, ConceptReference *ConceptRef,
ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction,
bool Dependent,
bool ContainsUnexpandedParameterPack);
+
+ ConceptSpecializationExpr(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
+ ASTConstraintSatisfaction *Satisfaction,
+ bool Dependent,
+ bool ContainsUnexpandedParameterPack);
ConceptSpecializationExpr(EmptyShell Empty);
public:
@@ -72,13 +82,25 @@ class ConceptSpecializationExpr final : public Expr {
ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction);
+ static ConceptSpecializationExpr *
+ Create(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
+ ASTConstraintSatisfaction *Satisfaction);
+
static ConceptSpecializationExpr *
Create(const ASTContext &C, ConceptReference *ConceptRef,
ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction, bool Dependent,
bool ContainsUnexpandedParameterPack);
+ static ConceptSpecializationExpr *
+ Create(const ASTContext &C, ConceptReference *ConceptRef,
+ ImplicitConceptSpecializationDecl *SpecDecl,
+ ASTConstraintSatisfaction *Satisfaction, bool Dependent,
+ bool ContainsUnexpandedParameterPack);
+
ArrayRef<TemplateArgument> getTemplateArguments() const {
+ assert(hasSpecializationDecl() && "Template Argument Decl not initialized");
return SpecDecl->getTemplateArguments();
}
@@ -113,8 +135,10 @@ class ConceptSpecializationExpr final : public Expr {
return ConceptRef->getConceptNameInfo();
}
+ bool hasSpecializationDecl() const { return SpecDecl != nullptr; }
+
const ImplicitConceptSpecializationDecl *getSpecializationDecl() const {
- assert(SpecDecl && "Template Argument Decl not initialized");
+ assert(hasSpecializationDecl() && "Template Argument Decl not initialized");
return SpecDecl;
}
@@ -445,6 +469,12 @@ class NestedRequirement : public Requirement {
"constructed with a ConstraintSatisfaction object");
}
+ NestedRequirement(Expr *Constraint,
+ const ASTConstraintSatisfaction *Satisfaction)
+ : Requirement(RK_Nested, Constraint->isInstantiationDependent(),
+ Constraint->containsUnexpandedParameterPack()),
+ Constraint(Constraint), Satisfaction(Satisfaction) {}
+
NestedRequirement(ASTContext &C, Expr *Constraint,
const ConstraintSatisfaction &Satisfaction)
: Requirement(RK_Nested, Constraint->isInstantiationDependent(),
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 3bc0a647ebf94f..0910f854e3e1c3 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -574,6 +574,10 @@ namespace clang {
ExpectedDecl VisitVarTemplateDecl(VarTemplateDecl *D);
ExpectedDecl VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D);
ExpectedDecl VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
+ ExpectedDecl VisitConceptDecl(ConceptDecl *D);
+ ExpectedDecl VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D);
+ ExpectedDecl VisitImplicitConceptSpecializationDecl(
+ ImplicitConceptSpecializationDecl *D);
// Importing statements
ExpectedStmt VisitStmt(Stmt *S);
@@ -690,6 +694,8 @@ namespace clang {
ExpectedStmt VisitTypeTraitExpr(TypeTraitExpr *E);
ExpectedStmt VisitCXXTypeidExpr(CXXTypeidExpr *E);
ExpectedStmt VisitCXXFoldExpr(CXXFoldExpr *E);
+ ExpectedStmt VisitRequiresExpr(RequiresExpr *E);
+ ExpectedStmt VisitConceptSpecializationExpr(ConceptSpecializationExpr *E);
// Helper for chaining together multiple imports. If an error is detected,
// subsequent imports will return default constructed nodes, so that failure
@@ -1072,6 +1078,136 @@ Expected<LambdaCapture> ASTNodeImporter::import(const LambdaCapture &From) {
EllipsisLoc);
}
+template <>
+Expected<concepts::Requirement::SubstitutionDiagnostic *>
+ASTNodeImporter::import(concepts::Requirement::SubstitutionDiagnostic *SD) {
+ ExpectedSLoc ToDiagLoc = Importer.Import(SD->DiagLoc);
+ if (!ToDiagLoc)
+ return ToDiagLoc.takeError();
+
+ auto &ToC = Importer.ToContext;
+ return new (ToC) concepts::Requirement::SubstitutionDiagnostic{
+ ToC.backupStr(SD->SubstitutedEntity), *ToDiagLoc,
+ ToC.backupStr(SD->DiagMessage)};
+}
+
+template <>
+Expected<concepts::ExprRequirement::ReturnTypeRequirement>
+ASTNodeImporter::import(
+ const concepts::ExprRequirement::ReturnTypeRequirement &R) {
+ if (R.isEmpty())
+ return concepts::ExprRequirement::ReturnTypeRequirement{};
+
+ if (R.isSubstitutionFailure()) {
+ auto ToSubstDiagOrErr = import(R.getSubstitutionDiagnostic());
+ if (!ToSubstDiagOrErr)
+ return ToSubstDiagOrErr.takeError();
+ return concepts::ExprRequirement::ReturnTypeRequirement(*ToSubstDiagOrErr);
+ }
+
+ auto TPLOrErr = import(R.getTypeConstraintTemplateParameterList());
+ if (!TPLOrErr)
+ return TPLOrErr.takeError();
+
+ return concepts::ExprRequirement::ReturnTypeRequirement(*TPLOrErr);
+}
+
+template <>
+Expected<concepts::ExprRequirement *>
+ASTNodeImporter::import(concepts::ExprRequirement *R) {
+ SourceLocation ToNoexceptLoc;
+ if (R->hasNoexceptRequirement()) {
+ auto ToNoexceptLocOrErr = Importer.Import(R->getNoexceptLoc());
+ if (!ToNoexceptLocOrErr)
+ return ToNoexceptLocOrErr.takeError();
+ ToNoexceptLoc = *ToNoexceptLocOrErr;
+ }
+
+ auto RetTypeRequirementOrErr = import(R->getReturnTypeRequirement());
+ if (!RetTypeRequirementOrErr)
+ return RetTypeRequirementOrErr.takeError();
+
+ auto RetTypeRequirement = *RetTypeRequirementOrErr;
+ auto &ToC = Importer.ToContext;
+ if (R->isExprSubstitutionFailure()) {
+ auto ToSubstDiagOrErr = import(R->getExprSubstitutionDiagnostic());
+ if (!ToSubstDiagOrErr)
+ return ToSubstDiagOrErr.takeError();
+
+ return new (ToC) concepts::ExprRequirement(
+ *ToSubstDiagOrErr, R->isSimple(), ToNoexceptLoc, RetTypeRequirement);
+ }
+
+ auto ToExprOrErr = Importer.Import(R->getExpr());
+ if (!ToExprOrErr)
+ return ToExprOrErr.takeError();
+
+ ConceptSpecializationExpr *ToCSE = nullptr;
+ if (R->getSatisfactionStatus() >=
+ concepts::ExprRequirement::SS_TypeRequirementSubstitutionFailure) {
+ auto ToCSEOrErr =
+ import(R->getReturnTypeRequirementSubstitutedConstraintExpr());
+ if (!ToCSEOrErr)
+ return ToCSEOrErr.takeError();
+ ToCSE = *ToCSEOrErr;
+ }
+
+ return new (ToC) concepts::ExprRequirement(*ToExprOrErr, R->isSimple(),
+ ToNoexceptLoc, RetTypeRequirement,
+ R->getSatisfactionStatus(), ToCSE);
+}
+
+template <>
+Expected<concepts::NestedRequirement *>
+ASTNodeImporter::import(concepts::NestedRequirement *R) {
+ auto &ToC = Importer.ToContext;
+ auto *ToASTSat =
+ ASTConstraintSatisfaction::Rebuild(ToC, R->getConstraintSatisfaction());
+
+ if (R->hasInvalidConstraint()) {
+ R->getInvalidConstraintEntity();
+ return new (ToC) concepts::NestedRequirement(
+ ToC.backupStr(R->getInvalidConstraintEntity()), ToASTSat);
+ }
+
+ Expr *FromExpr = R->getConstraintExpr();
+ auto ToExprOrErr = Importer.Import(FromExpr);
+ if (!ToExprOrErr)
+ return ToExprOrErr.takeError();
+
+ return new (ToC) concepts::NestedRequirement(
+ *ToExprOrErr,
+ ASTConstraintSatisfaction::Rebuild(ToC, R->getConstraintSatisfaction()));
+}
+
+template <>
+Expected<concepts::TypeRequirement *>
+ASTNodeImporter::import(concepts::TypeRequirement *R) {
+ auto &ToC = Importer.ToContext;
+ if (R->isSubstitutionFailure()) {
+ auto ToSubstDiagOrErr = import(R->getSubstitutionDiagnostic());
+ if (!ToSubstDiagOrErr)
+ return ToSubstDiagOrErr.takeError();
+ return new (ToC) concepts::TypeRequirement(*ToSubstDiagOrErr);
+ }
+
+ Expected<TypeSourceInfo *> ToTSI = Importer.Import(R->getType());
+ if (!ToTSI)
+ return ToTSI.takeError();
+ return new (ToC) concepts::TypeRequirement(*ToTSI);
+}
+
+template <>
+Expected<concepts::Requirement *>
+ASTNodeImporter::import(concepts::Requirement *R) {
+ auto Kind = R->getKind();
+ if (Kind == concepts::Requirement::RK_Type)
+ return import(cast<concepts::TypeRequirement>(R));
+ else if (Kind == concepts::Requirement::RK_Nested)
+ return import(cast<concepts::NestedRequirement>(R));
+ return import(cast<concepts::ExprRequirement>(R));
+}
+
template <typename T>
bool ASTNodeImporter::hasSameVisibilityContextAndLinkage(T *Found, T *From) {
if (Found->getLinkageInternal() != From->getLinkageInternal())
@@ -6788,6 +6924,81 @@ ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
return ToFunc;
}
+ExpectedDecl ASTNodeImporter::VisitConceptDecl(ConceptDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ DeclarationName Name;
+ SourceLocation Loc;
+ NamedDecl *ToD;
+
+ if (Error Err = ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
+ return std::move(Err);
+
+ if (ToD)
+ return ToD;
+
+ auto ParamsOrErr = import(D->getTemplateParameters());
+ if (!ParamsOrErr)
+ return ParamsOrErr.takeError();
+ TemplateParameterList *Params = *ParamsOrErr;
+
+ ExpectedExpr ToConstraintClauseOrErr = import(D->getConstraintExpr());
+ if (!ToConstraintClauseOrErr)
+ return ToConstraintClauseOrErr.takeError();
+
+ Expr *ToConstraintClause = *ToConstraintClauseOrErr;
+
+ ConceptDecl *ToConcept = nullptr;
+ if (GetImportedOrCreateDecl(ToConcept, D, Importer.getToContext(), DC, Loc,
+ Name, Params, ToConstraintClause))
+ return ToConcept;
+
+ addDeclToContexts(D, ToConcept);
+
+ return ToConcept;
+}
+
+ExpectedDecl
+ASTNodeImporter::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return std::move(Err);
+
+ ExpectedSLoc ToStartLocOrErr = import(D->getLocation());
+ if (!ToStartLocOrErr)
+ return ToStartLocOrErr.takeError();
+
+ SourceLocation ToStartLoc = *ToStartLocOrErr;
+
+ RequiresExprBodyDecl *ToD = nullptr;
+ if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, ToStartLoc))
+ return ToD;
+
+ return ToD;
+}
+
+ExpectedDecl ASTNodeImporter::VisitImplicitConceptSpecializationDecl(
+ ImplicitConceptSpecializationDecl *D) {
+ DeclContext *DC, *LexicalDC;
+ if (Error Err = ImportDeclContext(D, DC, LexicalDC))
+ return std::move(Err);
+
+ ExpectedSLoc ToLocOrErr = import(D->getLocation());
+ if (!ToLocOrErr)
+ return ToLocOrErr.takeError();
+
+ const auto &FromArgs = D->getTemplateArguments();
+ SmallVector<TemplateArgument, 4> ToArgs(FromArgs.size());
+ if (Error Err = ImportContainerChecked(FromArgs, ToArgs))
+ return std::move(Err);
+
+ ImplicitConceptSpecializationDecl *ToD = nullptr;
+ if (GetImportedOrCreateDecl(ToD, D, Importer.getToContext(), DC, *ToLocOrErr,
+ ToArgs))
+ return ToD;
+
+ return ToD;
+}
+
//----------------------------------------------------------------------------
// Import Statements
//----------------------------------------------------------------------------
@@ -9003,6 +9214,60 @@ ExpectedStmt ASTNodeImporter::VisitCXXFoldExpr(CXXFoldExpr *E) {
ToEllipsisLoc, ToRHS, ToRParenLoc, E->getNumExpansions());
}
+ExpectedStmt ASTNodeImporter::VisitRequiresExpr(RequiresExpr *E) {
+ auto ToBodyOrErr = import(E->getBody());
+ if (!ToBodyOrErr)
+ return ToBodyOrErr.takeError();
+
+ const auto &FromLocalParams = E->getLocalParameters();
+ SmallVector<ParmVarDecl *, 4> ToLocalParams(FromLocalParams.size());
+ if (Error Err = ImportContainerChecked(FromLocalParams, ToLocalParams))
+ return std::move(Err);
+
+ const auto &FromRequirements = E->getRequirements();
+ SmallVector<concepts::Requirement *, 4> ToRequirements(
+ FromRequirements.size());
+ if (Error Err = ImportContainerChecked(FromRequirements, ToRequirements))
+ return std::move(Err);
+
+ Error Err = Error::success();
+ SourceLocation RequiresKWLoc = importChecked(Err, E->getRequiresKWLoc());
+ SourceLocation ToLParenLoc = importChecked(Err, E->getLParenLoc());
+ SourceLocation ToRParenLoc = importChecked(Err, E->getRParenLoc());
+ SourceLocation ToRBrackeLoc = importChecked(Err, E->getRBraceLoc());
+
+ if (Err)
+ return std::move(Err);
+
+ return RequiresExpr::Create(Importer.getToContext(), RequiresKWLoc,
+ *ToBodyOrErr, ToLParenLoc, ToLocalParams,
+ ToRParenLoc, ToRequirements, ToRBrackeLoc);
+}
+
+ExpectedStmt
+ASTNodeImporter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
+ auto ToConceptRefOrErr = import(E->getConceptReference());
+ if (!ToConceptRefOrErr)
+ return ToConceptRefOrErr.takeError();
+
+ ImplicitConceptSpecializationDecl *ToSpecDecl = nullptr;
+ if (E->hasSpecializationDecl()) {
+ auto ToSpecDeclOrErr = import(E->getSpecializationDecl());
+ if (!ToSpecDeclOrErr)
+ return ToSpecDeclOrErr.takeError();
+ ToSpecDecl = *ToSpecDeclOrErr;
+ }
+
+ auto &ToC = Importer.ToContext;
+ auto IsDependent = E->isValueDependent();
+ return ConceptSpecializationExpr::Create(
+ ToC, *ToConceptRefOrErr, ToSpecDecl,
+ !IsDependent
+ ? ASTConstraintSatisfaction::Rebuild(ToC, E->getSatisfaction())
+ : nullptr,
+ IsDependent, E->containsUnexpandedParameterPack());
+}
+
Error ASTNodeImporter::ImportOverriddenMethods(CXXMethodDecl *ToMethod,
CXXMethodDecl *FromMethod) {
Error ImportErrors = Error::success();
diff --git a/clang/lib/AST/ExprConcepts.cpp b/clang/lib/AST/ExprConcepts.cpp
index 0704630c0fc266..072a5a4b25d0fb 100644
--- a/clang/lib/AST/ExprConcepts.cpp
+++ b/clang/lib/AST/ExprConcepts.cpp
@@ -34,11 +34,17 @@ ConceptSpecializationExpr::ConceptSpecializationExpr(
const ASTContext &C, ConceptReference *Loc,
ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction)
+ : ConceptSpecializationExpr(
+ C, Loc, SpecDecl,
+ Satisfaction ? ASTConstraintSatisfaction::Create(C, *Satisfaction)
+ : nullptr) {}
+
+ConceptSpecializationExpr::ConceptSpecializationExpr(
+ const ASTContext &C, ConceptReference *Loc,
+ ImplicitConceptSpecializationDecl *SpecDecl,
+ ASTConstraintSatisfaction *Satisfaction)
: Expr(ConceptSpecializationExprClass, C.BoolTy, VK_PRValue, OK_Ordinary),
- ConceptRef(Loc), SpecDecl(SpecDecl),
- Satisfaction(Satisfaction
- ? ASTConstraintSatisfaction::Create(C, *Satisfaction)
- : nullptr) {
+ ConceptRef(Loc), SpecDecl(SpecDecl), Satisfaction(Satisfaction) {
setDependence(computeDependence(this, /*ValueDependent=*/!Satisfaction));
// Currently guaranteed by the fact concepts can only be at namespace-scope.
@@ -63,16 +69,31 @@ ConceptSpecializationExpr::Create(const ASTContext &C, ConceptReference *Loc,
return new (C) ConceptSpecializationExpr(C, Loc, SpecDecl, Satisfaction);
}
+ConceptSpecializationExpr *
+ConceptSpecializationExpr::Create(const ASTContext &C, ConceptReference *Loc,
+ ImplicitConceptSpecializationDecl *SpecDecl,
+ ASTConstraintSatisfaction *Satisfaction) {
+ return new (C) ConceptSpecializationExpr(C, Loc, SpecDecl, Satisfaction);
+}
+
ConceptSpecializationExpr::ConceptSpecializationExpr(
const ASTContext &C, ConceptReference *Loc,
ImplicitConceptSpecializationDecl *SpecDecl,
const ConstraintSatisfaction *Satisfaction, bool Dependent,
bool ContainsUnexpandedParameterPack)
+ : ConceptSpecializationExpr(
+ C, Loc, SpecDecl,
+ Satisfaction ? ASTConstraintSatisfaction::Create(C, *Satisfaction)
+ : nullptr,
+ Dependent, ContainsUnexpandedParameterPack) {}
+
+ConceptSpecializationExpr::ConceptSpecializationExpr(
+ const ASTContext &C, ConceptReference *Loc,
+ ImplicitConceptSpecializationDecl *SpecDecl,
+ ASTConstraintSatisfaction *Satisfaction, bool Dependent,
+ bool ContainsUnexpandedParameterPack)
: Expr(ConceptSpecializationExprClass, C.BoolTy, VK_PRValue, OK_Ordinary),
- ConceptRef(Loc), SpecDecl(SpecDecl),
- Satisfaction(Satisfaction
- ? ASTConstraintSatisfaction::Create(C, *Satisfaction)
- : nullptr) {
+ ConceptRef(Loc), SpecDecl(SpecDecl), Satisfaction(Satisfaction) {
ExprDependence D = ExprDependence::None;
if (!Satisfaction)
D |= ExprDependence::Value;
@@ -94,6 +115,17 @@ ConceptSpecializationExpr::Create(const ASTContext &C, ConceptReference *Loc,
ContainsUnexpandedParameterPack);
}
+ConceptSpecializationExpr *
+ConceptSpecializationExpr::Create(const ASTContext &C, ConceptReference *Loc,
+ ImplicitConceptSpecializationDecl *SpecDecl,
+ ASTConstraintSatisfaction *Satisfaction,
+ bool Dependent,
+ bool ContainsUnexpandedParameterPack) {
+ return new (C)
+ ConceptSpecializationExpr(C, Loc, SpecDecl, Satisfaction, Dependent,
+ ContainsUnexpandedParameterPack);
+}
+
const TypeConstraint *
concepts::ExprRequirement::ReturnTypeRequirement::getTypeConstraint() const {
assert(isTypeConstraint());
@@ -193,3 +225,61 @@ RequiresExpr::Create(ASTContext &C, EmptyShell Empty,
alignof(RequiresExpr));
return new (Mem) RequiresExpr(C, Empty, NumLocalParameters, NumRequirements);
}
+
+concepts::ExprRequirement::ExprRequirement(
+ Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
+ ReturnTypeRequirement Req, SatisfactionStatus Status,
+ ConceptSpecializationExpr *SubstitutedConstraintExpr)
+ : Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent,
+ Status == SS_Dependent &&
+ (E->containsUnexpandedParameterPack() ||
+ Req.containsUnexpandedParameterPack()),
+ Status == SS_Satisfied),
+ Value(E), NoexceptLoc(NoexceptLoc), TypeReq(Req),
+ SubstitutedConstraintExpr(SubstitutedConstraintExpr), Status(Status) {
+ assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
+ "Simple requirement must not have a return type requirement or a "
+ "noexcept specification");
+ assert((Status > SS_TypeRequirementSubstitutionFailure &&
+ Req.isTypeConstraint()) == (SubstitutedConstraintExpr != nullptr));
+}
+
+concepts::ExprRequirement::ExprRequirement(
+ SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple,
+ SourceLocation NoexceptLoc, ReturnTypeRequirement Req)
+ : Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(),
+ Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false),
+ Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req),
+ Status(SS_ExprSubstitutionFailure) {
+ assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) &&
+ "Simple requirement must not have a return type requirement or a "
+ "noexcept specification");
+}...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/104731
More information about the cfe-commits
mailing list