summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTReaderStmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Serialization/ASTReaderStmt.cpp')
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp162
1 files changed, 143 insertions, 19 deletions
diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index f558c26b5f1..5dd0ef9d43c 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -724,27 +724,15 @@ void ASTStmtReader::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *E) {
E->setRParenLoc(readSourceLocation());
}
-void ASTStmtReader::VisitConceptSpecializationExpr(
- ConceptSpecializationExpr *E) {
- VisitExpr(E);
- unsigned NumTemplateArgs = Record.readInt();
- E->NestedNameSpec = Record.readNestedNameSpecifierLoc();
- E->TemplateKWLoc = Record.readSourceLocation();
- E->ConceptName = Record.readDeclarationNameInfo();
- E->NamedConcept = readDeclAs<ConceptDecl>();
- E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
- llvm::SmallVector<TemplateArgument, 4> Args;
- for (unsigned I = 0; I < NumTemplateArgs; ++I)
- Args.push_back(Record.readTemplateArgument());
- E->setTemplateArguments(Args);
+static ConstraintSatisfaction
+readConstraintSatisfaction(ASTRecordReader &Record) {
ConstraintSatisfaction Satisfaction;
Satisfaction.IsSatisfied = Record.readInt();
if (!Satisfaction.IsSatisfied) {
unsigned NumDetailRecords = Record.readInt();
for (unsigned i = 0; i != NumDetailRecords; ++i) {
Expr *ConstraintExpr = Record.readExpr();
- bool IsDiagnostic = Record.readInt();
- if (IsDiagnostic) {
+ if (bool IsDiagnostic = Record.readInt()) {
SourceLocation DiagLocation = Record.readSourceLocation();
std::string DiagMessage = Record.readString();
Satisfaction.Details.emplace_back(
@@ -755,8 +743,137 @@ void ASTStmtReader::VisitConceptSpecializationExpr(
Satisfaction.Details.emplace_back(ConstraintExpr, Record.readExpr());
}
}
- E->Satisfaction = ASTConstraintSatisfaction::Create(Record.getContext(),
- Satisfaction);
+ return Satisfaction;
+}
+
+void ASTStmtReader::VisitConceptSpecializationExpr(
+ ConceptSpecializationExpr *E) {
+ VisitExpr(E);
+ unsigned NumTemplateArgs = Record.readInt();
+ E->NestedNameSpec = Record.readNestedNameSpecifierLoc();
+ E->TemplateKWLoc = Record.readSourceLocation();
+ E->ConceptName = Record.readDeclarationNameInfo();
+ E->NamedConcept = readDeclAs<ConceptDecl>();
+ E->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
+ llvm::SmallVector<TemplateArgument, 4> Args;
+ for (unsigned I = 0; I < NumTemplateArgs; ++I)
+ Args.push_back(Record.readTemplateArgument());
+ E->setTemplateArguments(Args);
+ E->Satisfaction = E->isValueDependent() ? nullptr :
+ ASTConstraintSatisfaction::Create(Record.getContext(),
+ readConstraintSatisfaction(Record));
+}
+
+static concepts::Requirement::SubstitutionDiagnostic *
+readSubstitutionDiagnostic(ASTRecordReader &Record) {
+ std::string SubstitutedEntity = Record.readString();
+ SourceLocation DiagLoc = Record.readSourceLocation();
+ std::string DiagMessage = Record.readString();
+ return new (Record.getContext())
+ concepts::Requirement::SubstitutionDiagnostic{SubstitutedEntity, DiagLoc,
+ DiagMessage};
+}
+
+void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) {
+ VisitExpr(E);
+ unsigned NumLocalParameters = Record.readInt();
+ unsigned NumRequirements = Record.readInt();
+ E->RequiresExprBits.RequiresKWLoc = Record.readSourceLocation();
+ E->RequiresExprBits.IsSatisfied = Record.readInt();
+ E->Body = Record.readDeclAs<RequiresExprBodyDecl>();
+ llvm::SmallVector<ParmVarDecl *, 4> LocalParameters;
+ for (unsigned i = 0; i < NumLocalParameters; ++i)
+ LocalParameters.push_back(cast<ParmVarDecl>(Record.readDecl()));
+ std::copy(LocalParameters.begin(), LocalParameters.end(),
+ E->getTrailingObjects<ParmVarDecl *>());
+ llvm::SmallVector<concepts::Requirement *, 4> Requirements;
+ for (unsigned i = 0; i < NumRequirements; ++i) {
+ auto RK =
+ static_cast<concepts::Requirement::RequirementKind>(Record.readInt());
+ concepts::Requirement *R = nullptr;
+ switch (RK) {
+ case concepts::Requirement::RK_Type: {
+ auto Status =
+ static_cast<concepts::TypeRequirement::SatisfactionStatus>(
+ Record.readInt());
+ if (Status == concepts::TypeRequirement::SS_SubstitutionFailure)
+ R = new (Record.getContext())
+ concepts::TypeRequirement(readSubstitutionDiagnostic(Record));
+ else
+ R = new (Record.getContext())
+ concepts::TypeRequirement(Record.readTypeSourceInfo());
+ } break;
+ case concepts::Requirement::RK_Simple:
+ case concepts::Requirement::RK_Compound: {
+ auto Status =
+ static_cast<concepts::ExprRequirement::SatisfactionStatus>(
+ Record.readInt());
+ llvm::PointerUnion<concepts::Requirement::SubstitutionDiagnostic *,
+ Expr *> E;
+ if (Status == concepts::ExprRequirement::SS_ExprSubstitutionFailure) {
+ E = readSubstitutionDiagnostic(Record);
+ } else
+ E = Record.readExpr();
+
+ llvm::Optional<concepts::ExprRequirement::ReturnTypeRequirement> Req;
+ ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr;
+ SourceLocation NoexceptLoc;
+ if (RK == concepts::Requirement::RK_Simple) {
+ Req.emplace();
+ } else {
+ NoexceptLoc = Record.readSourceLocation();
+ switch (auto returnTypeRequirementKind = Record.readInt()) {
+ case 0:
+ // No return type requirement.
+ Req.emplace();
+ break;
+ case 1: {
+ // type-constraint
+ TemplateParameterList *TPL = Record.readTemplateParameterList();
+ if (Status >=
+ concepts::ExprRequirement::SS_ConstraintsNotSatisfied)
+ SubstitutedConstraintExpr =
+ cast<ConceptSpecializationExpr>(Record.readExpr());
+ Req.emplace(TPL);
+ } break;
+ case 2:
+ // Substitution failure
+ Req.emplace(readSubstitutionDiagnostic(Record));
+ break;
+ }
+ }
+ if (Expr *Ex = E.dyn_cast<Expr *>())
+ R = new (Record.getContext()) concepts::ExprRequirement(
+ Ex, RK == concepts::Requirement::RK_Simple, NoexceptLoc,
+ std::move(*Req), Status, SubstitutedConstraintExpr);
+ else
+ R = new (Record.getContext()) concepts::ExprRequirement(
+ E.get<concepts::Requirement::SubstitutionDiagnostic *>(),
+ RK == concepts::Requirement::RK_Simple, NoexceptLoc,
+ std::move(*Req));
+ } break;
+ case concepts::Requirement::RK_Nested: {
+ if (bool IsSubstitutionDiagnostic = Record.readInt()) {
+ R = new (Record.getContext()) concepts::NestedRequirement(
+ readSubstitutionDiagnostic(Record));
+ break;
+ }
+ Expr *E = Record.readExpr();
+ if (E->isInstantiationDependent())
+ R = new (Record.getContext()) concepts::NestedRequirement(E);
+ else
+ R = new (Record.getContext())
+ concepts::NestedRequirement(Record.getContext(), E,
+ readConstraintSatisfaction(Record));
+ } break;
+ }
+ if (!R)
+ continue;
+ Requirements.push_back(R);
+ }
+ std::copy(Requirements.begin(), Requirements.end(),
+ E->getTrailingObjects<concepts::Requirement *>());
+ E->RBraceLoc = Record.readSourceLocation();
}
void ASTStmtReader::VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
@@ -3566,11 +3683,18 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
S = new (Context) DependentCoawaitExpr(Empty);
break;
- case EXPR_CONCEPT_SPECIALIZATION:
+ case EXPR_CONCEPT_SPECIALIZATION: {
unsigned numTemplateArgs = Record[ASTStmtReader::NumExprFields];
S = ConceptSpecializationExpr::Create(Context, Empty, numTemplateArgs);
break;
-
+ }
+
+ case EXPR_REQUIRES:
+ unsigned numLocalParameters = Record[ASTStmtReader::NumExprFields];
+ unsigned numRequirement = Record[ASTStmtReader::NumExprFields + 1];
+ S = RequiresExpr::Create(Context, Empty, numLocalParameters,
+ numRequirement);
+ break;
}
// We hit a STMT_STOP, so we're done with this expression.
OpenPOWER on IntegriCloud