@@ -1000,73 +1000,85 @@ class ResultBuilderTransform
1000
1000
return failTransform (stmt); \
1001
1001
}
1002
1002
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 ()) {
1019
1016
// Just ignore #if; the chosen children should appear in
1020
1017
// the surrounding context. This isn't good for source
1021
1018
// tools but it at least works.
1022
- case DeclKind::IfConfig:
1019
+ case DeclKind::IfConfig:
1023
1020
// Skip #warning/#error; we'll handle them when applying
1024
1021
// 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
+ }
1035
1034
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;
1037
1040
}
1038
1041
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);
1045
1044
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);
1048
1048
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
+ }
1052
1054
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
+ }
1058
1060
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
+ }
1064
1068
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
+ }
1070
1082
}
1071
1083
1072
1084
// Synthesize `buildBlock` or `buildPartial` based on captured arguments.
0 commit comments