Skip to content

Commit 1846276

Browse files
committed
[CS] Factor out brace element handling in a couple of cases
Split out brace element handling for a couple of walkers into a new function. The diff for this is best viewed without whitespace changes. This should be NFC.
1 parent 0faa0b6 commit 1846276

File tree

2 files changed

+89
-72
lines changed

2 files changed

+89
-72
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 66 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,73 +1000,85 @@ class ResultBuilderTransform
10001000
return failTransform(stmt); \
10011001
}
10021002

1003-
std::pair<NullablePtr<VarDecl>, Optional<UnsupportedElt>>
1004-
transform(BraceStmt *braceStmt, SmallVectorImpl<ASTNode> &newBody) {
1005-
SmallVector<Expr *, 4> buildBlockArguments;
1006-
1007-
auto failTransform = [&](UnsupportedElt unsupported) {
1008-
return std::make_pair(nullptr, unsupported);
1009-
};
1010-
1011-
for (auto element : braceStmt->getElements()) {
1012-
if (auto *returnStmt = getAsStmt<ReturnStmt>(element)) {
1013-
assert(returnStmt->isImplicit());
1014-
element = returnStmt->getResult();
1015-
}
1016-
1017-
if (auto *decl = element.dyn_cast<Decl *>()) {
1018-
switch (decl->getKind()) {
1003+
/// Visit the element of a brace statement, returning \c None if the element
1004+
/// was transformed successfully, or an unsupported element if the element
1005+
/// cannot be handled.
1006+
Optional<UnsupportedElt>
1007+
transformBraceElement(ASTNode element, SmallVectorImpl<ASTNode> &newBody,
1008+
SmallVectorImpl<Expr *> &buildBlockArguments) {
1009+
if (auto *returnStmt = getAsStmt<ReturnStmt>(element)) {
1010+
assert(returnStmt->isImplicit());
1011+
element = returnStmt->getResult();
1012+
}
1013+
1014+
if (auto *decl = element.dyn_cast<Decl *>()) {
1015+
switch (decl->getKind()) {
10191016
// Just ignore #if; the chosen children should appear in
10201017
// the surrounding context. This isn't good for source
10211018
// tools but it at least works.
1022-
case DeclKind::IfConfig:
1019+
case DeclKind::IfConfig:
10231020
// Skip #warning/#error; we'll handle them when applying
10241021
// the builder.
1025-
case DeclKind::PoundDiagnostic:
1026-
case DeclKind::PatternBinding:
1027-
case DeclKind::Var:
1028-
case DeclKind::Param:
1029-
newBody.push_back(element);
1030-
break;
1031-
1032-
default:
1033-
return failTransform(decl);
1034-
}
1022+
case DeclKind::PoundDiagnostic:
1023+
case DeclKind::PatternBinding:
1024+
case DeclKind::Var:
1025+
case DeclKind::Param:
1026+
newBody.push_back(element);
1027+
return None;
1028+
1029+
default:
1030+
return UnsupportedElt(decl);
1031+
}
1032+
llvm_unreachable("Unhandled case in switch!");
1033+
}
10351034

1036-
continue;
1035+
if (auto *stmt = element.dyn_cast<Stmt *>()) {
1036+
// Throw is allowed as is.
1037+
if (auto *throwStmt = dyn_cast<ThrowStmt>(stmt)) {
1038+
newBody.push_back(throwStmt);
1039+
return None;
10371040
}
10381041

1039-
if (auto *stmt = element.dyn_cast<Stmt *>()) {
1040-
// Throw is allowed as is.
1041-
if (auto *throwStmt = dyn_cast<ThrowStmt>(stmt)) {
1042-
newBody.push_back(throwStmt);
1043-
continue;
1044-
}
1042+
// Allocate variable with a placeholder type
1043+
auto *resultVar = buildPlaceholderVar(stmt->getStartLoc(), newBody);
10451044

1046-
// Allocate variable with a placeholder type
1047-
auto *resultVar = buildPlaceholderVar(stmt->getStartLoc(), newBody);
1045+
auto result = visit(stmt, resultVar);
1046+
if (!result)
1047+
return UnsupportedElt(stmt);
10481048

1049-
auto result = visit(stmt, resultVar);
1050-
if (!result)
1051-
return failTransform(stmt);
1049+
newBody.push_back(result.get());
1050+
buildBlockArguments.push_back(
1051+
builder.buildVarRef(resultVar, stmt->getStartLoc()));
1052+
return None;
1053+
}
10521054

1053-
newBody.push_back(result.get());
1054-
buildBlockArguments.push_back(
1055-
builder.buildVarRef(resultVar, stmt->getStartLoc()));
1056-
continue;
1057-
}
1055+
auto *expr = element.get<Expr *>();
1056+
if (builder.supports(ctx.Id_buildExpression)) {
1057+
expr = builder.buildCall(expr->getLoc(), ctx.Id_buildExpression, {expr},
1058+
{Identifier()});
1059+
}
10581060

1059-
auto *expr = element.get<Expr *>();
1060-
if (builder.supports(ctx.Id_buildExpression)) {
1061-
expr = builder.buildCall(expr->getLoc(), ctx.Id_buildExpression, {expr},
1062-
{Identifier()});
1063-
}
1061+
auto *capture = captureExpr(expr, newBody);
1062+
// A reference to the synthesized variable is passed as an argument
1063+
// to buildBlock.
1064+
buildBlockArguments.push_back(
1065+
builder.buildVarRef(capture, element.getStartLoc()));
1066+
return None;
1067+
}
10641068

1065-
auto *capture = captureExpr(expr, newBody);
1066-
// A reference to the synthesized variable is passed as an argument
1067-
// to buildBlock.
1068-
buildBlockArguments.push_back(
1069-
builder.buildVarRef(capture, element.getStartLoc()));
1069+
std::pair<NullablePtr<VarDecl>, Optional<UnsupportedElt>>
1070+
transform(BraceStmt *braceStmt, SmallVectorImpl<ASTNode> &newBody) {
1071+
SmallVector<Expr *, 4> buildBlockArguments;
1072+
1073+
auto failTransform = [&](UnsupportedElt unsupported) {
1074+
return std::make_pair(nullptr, unsupported);
1075+
};
1076+
1077+
for (auto element : braceStmt->getElements()) {
1078+
if (auto unsupported =
1079+
transformBraceElement(element, newBody, buildBlockArguments)) {
1080+
return failTransform(*unsupported);
1081+
}
10701082
}
10711083

10721084
// Synthesize `buildBlock` or `buildPartial` based on captured arguments.

lib/Sema/CSSyntacticElement.cpp

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,6 +1512,27 @@ class SyntacticElementSolutionApplication
15121512
return caseStmt;
15131513
}
15141514

1515+
ASTNode visitBraceElement(ASTNode node) {
1516+
auto &cs = solution.getConstraintSystem();
1517+
if (auto *expr = node.dyn_cast<Expr *>()) {
1518+
// Rewrite the expression.
1519+
auto target = *cs.getSolutionApplicationTarget(expr);
1520+
if (auto rewrittenTarget = rewriteTarget(target)) {
1521+
node = rewrittenTarget->getAsExpr();
1522+
1523+
if (target.isDiscardedExpr())
1524+
TypeChecker::checkIgnoredExpr(castToExpr(node));
1525+
} else {
1526+
hadError = true;
1527+
}
1528+
} else if (auto stmt = node.dyn_cast<Stmt *>()) {
1529+
node = visit(stmt);
1530+
} else {
1531+
visitDecl(node.get<Decl *>());
1532+
}
1533+
return node;
1534+
}
1535+
15151536
ASTNode visitBraceStmt(BraceStmt *braceStmt) {
15161537
auto &cs = solution.getConstraintSystem();
15171538

@@ -1527,24 +1548,8 @@ class SyntacticElementSolutionApplication
15271548
}
15281549
}
15291550

1530-
for (auto &node : braceStmt->getElements()) {
1531-
if (auto expr = node.dyn_cast<Expr *>()) {
1532-
// Rewrite the expression.
1533-
auto target = *cs.getSolutionApplicationTarget(expr);
1534-
if (auto rewrittenTarget = rewriteTarget(target)) {
1535-
node = rewrittenTarget->getAsExpr();
1536-
1537-
if (target.isDiscardedExpr())
1538-
TypeChecker::checkIgnoredExpr(castToExpr(node));
1539-
} else {
1540-
hadError = true;
1541-
}
1542-
} else if (auto stmt = node.dyn_cast<Stmt *>()) {
1543-
node = visit(stmt);
1544-
} else {
1545-
visitDecl(node.get<Decl *>());
1546-
}
1547-
}
1551+
for (auto &node : braceStmt->getElements())
1552+
node = visitBraceElement(node);
15481553

15491554
// Source compatibility workaround.
15501555
//

0 commit comments

Comments
 (0)