Commit e65b9e8f7b
Changed files (3)
src-self-hosted
test
src-self-hosted/clang.zig
@@ -79,6 +79,7 @@ pub const ZigClangPreprocessingRecord = @OpaqueType();
pub const ZigClangFloatingLiteral = @OpaqueType();
pub const ZigClangConstantExpr = @OpaqueType();
pub const ZigClangCharacterLiteral = @OpaqueType();
+pub const ZigClangStmtExpr = @OpaqueType();
pub const ZigClangBO = extern enum {
PtrMemD,
@@ -1095,3 +1096,5 @@ pub extern fn ZigClangCharacterLiteral_getBeginLoc(*const ZigClangCharacterLiter
pub extern fn ZigClangCharacterLiteral_getKind(*const ZigClangCharacterLiteral) ZigClangCharacterLiteral_CharacterKind;
pub extern fn ZigClangCharacterLiteral_getValue(*const ZigClangCharacterLiteral) c_uint;
+pub extern fn ZigClangStmtExpr_getSubStmt( *const ZigClangStmtExpr) *const ZigClangCompoundStmt;
+
src-self-hosted/translate_c.zig
@@ -855,6 +855,7 @@ fn transStmt(
.ConstantExprClass => return transConstantExpr(rp, scope, @ptrCast(*const ZigClangExpr, stmt), result_used),
.PredefinedExprClass => return transPredefinedExpr(rp, scope, @ptrCast(*const ZigClangPredefinedExpr, stmt), result_used),
.CharacterLiteralClass => return transCharLiteral(rp, scope, @ptrCast(*const ZigClangCharacterLiteral, stmt), result_used),
+ .StmtExprClass => return transStmtExpr(rp, scope, @ptrCast(*const ZigClangStmtExpr, stmt), result_used),
else => {
return revertAndWarn(
rp,
@@ -1165,12 +1166,9 @@ fn transImplicitCastExpr(
const src_type = getExprQualType(c, sub_expr);
return transCCast(rp, scope, ZigClangImplicitCastExpr_getBeginLoc(expr), dest_type, src_type, sub_expr_node);
},
- .FunctionToPointerDecay, .ArrayToPointerDecay => {
+ .LValueToRValue, .NoOp, .FunctionToPointerDecay, .ArrayToPointerDecay => {
return maybeSuppressResult(rp, scope, result_used, sub_expr_node);
},
- .LValueToRValue, .NoOp => {
- return transExpr(rp, scope, sub_expr, .used, .r_value);
- },
.NullToPointer => {
return try transCreateNodeNullLiteral(rp.c);
},
@@ -1960,6 +1958,38 @@ fn transCharLiteral(
}
}
+fn transStmtExpr(rp: RestorePoint, scope: *Scope, stmt: *const ZigClangStmtExpr, used: ResultUsed) TransError!*ast.Node {
+ const comp = ZigClangStmtExpr_getSubStmt(stmt);
+ if (used == .unused) {
+ return transCompoundStmt(rp, scope, comp);
+ }
+ const lparen = try appendToken(rp.c, .LParen, "(");
+ const block_scope = try Scope.Block.init(rp.c, scope, "blk");
+ const block = try transCreateNodeBlock(rp.c, "blk");
+ block_scope.block_node = block;
+
+ var it = ZigClangCompoundStmt_body_begin(comp);
+ const end_it = ZigClangCompoundStmt_body_end(comp);
+ while (it != end_it - 1) : (it += 1) {
+ const result = try transStmt(rp, &block_scope.base, it[0], .unused, .r_value);
+ if (result != &block.base)
+ try block.statements.push(result);
+ }
+ const break_node = try transCreateNodeBreak(rp.c, "blk");
+ break_node.rhs = try transStmt(rp, &block_scope.base, it[0], .used, .r_value);
+ _ = try appendToken(rp.c, .Semicolon, ";");
+ try block.statements.push(&break_node.base);
+ block.rbrace = try appendToken(rp.c, .RBrace, "}");
+ const rparen = try appendToken(rp.c, .RParen, ")");
+ const grouped_expr = try rp.c.a().create(ast.Node.GroupedExpression);
+ grouped_expr.* = .{
+ .lparen = lparen,
+ .expr = &block.base,
+ .rparen = rparen,
+ };
+ return maybeSuppressResult(rp, scope, used, &grouped_expr.base);
+}
+
fn transCPtrCast(
rp: RestorePoint,
loc: ZigClangSourceLocation,
test/translate_c.zig
@@ -1476,6 +1476,24 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
+ cases.add_2("statement expression",
+ \\int foo(void) {
+ \\ return ({
+ \\ int a = 1;
+ \\ a;
+ \\ a;
+ \\ });
+ \\}
+ , &[_][]const u8{
+ \\pub export fn foo() c_int {
+ \\ return (blk: {
+ \\ var a: c_int = 1;
+ \\ _ = a;
+ \\ break :blk a;
+ \\ });
+ \\}
+ });
+
/////////////// Cases for only stage1 which are TODO items for stage2 ////////////////
cases.addAllowWarnings("simple data types",
@@ -1723,22 +1741,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
});
- cases.addC("statement expression",
- \\int foo(void) {
- \\ return ({
- \\ int a = 1;
- \\ a;
- \\ });
- \\}
- , &[_][]const u8{
- \\pub export fn foo() c_int {
- \\ return x: {
- \\ var a: c_int = 1;
- \\ break :x a;
- \\ };
- \\}
- });
-
cases.addC("__extension__ cast",
\\int foo(void) {
\\ return __extension__ 1;
@@ -2609,4 +2611,20 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return (a & b) ^ (a | b);
\\}
});
+
+ cases.addC("statement expression",
+ \\int foo(void) {
+ \\ return ({
+ \\ int a = 1;
+ \\ a;
+ \\ });
+ \\}
+ , &[_][]const u8{
+ \\pub export fn foo() c_int {
+ \\ return x: {
+ \\ var a: c_int = 1;
+ \\ break :x a;
+ \\ };
+ \\}
+ });
}