|
13 | 13 |
|
14 | 14 | #include "clang/AST/ASTConcept.h"
|
15 | 15 | #include "clang/AST/ASTContext.h"
|
| 16 | +#include "clang/AST/ExprConcepts.h" |
16 | 17 | #include "clang/AST/PrettyPrinter.h"
|
17 | 18 | #include "llvm/ADT/StringExtras.h"
|
18 | 19 |
|
@@ -107,3 +108,61 @@ void ConceptReference::print(llvm::raw_ostream &OS,
|
107 | 108 | OS << ">";
|
108 | 109 | }
|
109 | 110 | }
|
| 111 | + |
| 112 | +concepts::ExprRequirement::ExprRequirement( |
| 113 | + Expr *E, bool IsSimple, SourceLocation NoexceptLoc, |
| 114 | + ReturnTypeRequirement Req, SatisfactionStatus Status, |
| 115 | + ConceptSpecializationExpr *SubstitutedConstraintExpr) |
| 116 | + : Requirement(IsSimple ? RK_Simple : RK_Compound, Status == SS_Dependent, |
| 117 | + Status == SS_Dependent && |
| 118 | + (E->containsUnexpandedParameterPack() || |
| 119 | + Req.containsUnexpandedParameterPack()), |
| 120 | + Status == SS_Satisfied), |
| 121 | + Value(E), NoexceptLoc(NoexceptLoc), TypeReq(Req), |
| 122 | + SubstitutedConstraintExpr(SubstitutedConstraintExpr), Status(Status) { |
| 123 | + assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) && |
| 124 | + "Simple requirement must not have a return type requirement or a " |
| 125 | + "noexcept specification"); |
| 126 | + assert((Status > SS_TypeRequirementSubstitutionFailure && |
| 127 | + Req.isTypeConstraint()) == (SubstitutedConstraintExpr != nullptr)); |
| 128 | +} |
| 129 | + |
| 130 | +concepts::ExprRequirement::ExprRequirement( |
| 131 | + SubstitutionDiagnostic *ExprSubstDiag, bool IsSimple, |
| 132 | + SourceLocation NoexceptLoc, ReturnTypeRequirement Req) |
| 133 | + : Requirement(IsSimple ? RK_Simple : RK_Compound, Req.isDependent(), |
| 134 | + Req.containsUnexpandedParameterPack(), /*IsSatisfied=*/false), |
| 135 | + Value(ExprSubstDiag), NoexceptLoc(NoexceptLoc), TypeReq(Req), |
| 136 | + Status(SS_ExprSubstitutionFailure) { |
| 137 | + assert((!IsSimple || (Req.isEmpty() && NoexceptLoc.isInvalid())) && |
| 138 | + "Simple requirement must not have a return type requirement or a " |
| 139 | + "noexcept specification"); |
| 140 | +} |
| 141 | + |
| 142 | +concepts::ExprRequirement::ReturnTypeRequirement::ReturnTypeRequirement( |
| 143 | + TemplateParameterList *TPL) |
| 144 | + : TypeConstraintInfo(TPL, false) { |
| 145 | + assert(TPL->size() == 1); |
| 146 | + const TypeConstraint *TC = |
| 147 | + cast<TemplateTypeParmDecl>(TPL->getParam(0))->getTypeConstraint(); |
| 148 | + assert(TC && |
| 149 | + "TPL must have a template type parameter with a type constraint"); |
| 150 | + auto *Constraint = |
| 151 | + cast<ConceptSpecializationExpr>(TC->getImmediatelyDeclaredConstraint()); |
| 152 | + bool Dependent = |
| 153 | + Constraint->getTemplateArgsAsWritten() && |
| 154 | + TemplateSpecializationType::anyInstantiationDependentTemplateArguments( |
| 155 | + Constraint->getTemplateArgsAsWritten()->arguments().drop_front(1)); |
| 156 | + TypeConstraintInfo.setInt(Dependent ? true : false); |
| 157 | +} |
| 158 | + |
| 159 | +concepts::TypeRequirement::TypeRequirement(TypeSourceInfo *T) |
| 160 | + : Requirement(RK_Type, T->getType()->isInstantiationDependentType(), |
| 161 | + T->getType()->containsUnexpandedParameterPack(), |
| 162 | + // We reach this ctor with either dependent types (in which |
| 163 | + // IsSatisfied doesn't matter) or with non-dependent type in |
| 164 | + // which the existence of the type indicates satisfaction. |
| 165 | + /*IsSatisfied=*/true), |
| 166 | + Value(T), |
| 167 | + Status(T->getType()->isInstantiationDependentType() ? SS_Dependent |
| 168 | + : SS_Satisfied) {} |
0 commit comments