| author | |
| committer | |
| log | 13f782426660f49eb6ee7561ecee9237c22b4dc9 |
| tree | 34ca1e3a1b3fcf2fb9e7f1c83e7645ba1e8263c1 |
| parent | 58c97b3561c39036c2db1875d5a1b5125dd580ef |
| parent | 979c69d6b27a38e89ac85eb7db4f0c03c19433d5 |
| signature |
Generate compilable code for array inits3 files changed, 58 insertions(+), 14 deletions(-)
src-self-hosted/translate_c.zig+34-6| ... | @@ -1991,6 +1991,29 @@ fn transInitListExprRecord( | ... | @@ -1991,6 +1991,29 @@ fn transInitListExprRecord( |
| 1991 | return &init_node.base; | 1991 | return &init_node.base; |
| 1992 | } | 1992 | } |
| 1993 | 1993 | ||
| 1994 | fn transCreateNodeArrayType( | ||
| 1995 | rp: RestorePoint, | ||
| 1996 | source_loc: ZigClangSourceLocation, | ||
| 1997 | ty: *const ZigClangType, | ||
| 1998 | len: var, | ||
| 1999 | ) TransError!*ast.Node { | ||
| 2000 | var node = try transCreateNodePrefixOp( | ||
| 2001 | rp.c, | ||
| 2002 | .{ | ||
| 2003 | .ArrayType = .{ | ||
| 2004 | .len_expr = undefined, | ||
| 2005 | .sentinel = null, | ||
| 2006 | }, | ||
| 2007 | }, | ||
| 2008 | .LBracket, | ||
| 2009 | "[", | ||
| 2010 | ); | ||
| 2011 | node.op.ArrayType.len_expr = try transCreateNodeInt(rp.c, len); | ||
| 2012 | _ = try appendToken(rp.c, .RBracket, "]"); | ||
| 2013 | node.rhs = try transType(rp, ty, source_loc); | ||
| 2014 | return &node.base; | ||
| 2015 | } | ||
| 2016 | |||
| 1994 | fn transInitListExprArray( | 2017 | fn transInitListExprArray( |
| 1995 | rp: RestorePoint, | 2018 | rp: RestorePoint, |
| 1996 | scope: *Scope, | 2019 | scope: *Scope, |
| ... | @@ -2011,8 +2034,13 @@ fn transInitListExprArray( | ... | @@ -2011,8 +2034,13 @@ fn transInitListExprArray( |
| 2011 | var init_node: *ast.Node.SuffixOp = undefined; | 2034 | var init_node: *ast.Node.SuffixOp = undefined; |
| 2012 | var cat_tok: ast.TokenIndex = undefined; | 2035 | var cat_tok: ast.TokenIndex = undefined; |
| 2013 | if (init_count != 0) { | 2036 | if (init_count != 0) { |
| 2014 | const dot_tok = try appendToken(rp.c, .Period, "."); | 2037 | const ty_node = try transCreateNodeArrayType( |
| 2015 | init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok); | 2038 | rp, |
| 2039 | loc, | ||
| 2040 | ZigClangQualType_getTypePtr(child_qt), | ||
| 2041 | init_count, | ||
| 2042 | ); | ||
| 2043 | init_node = try transCreateNodeArrayInitializer(rp.c, ty_node); | ||
| 2016 | var i: c_uint = 0; | 2044 | var i: c_uint = 0; |
| 2017 | while (i < init_count) : (i += 1) { | 2045 | while (i < init_count) : (i += 1) { |
| 2018 | const elem_expr = ZigClangInitListExpr_getInit(expr, i); | 2046 | const elem_expr = ZigClangInitListExpr_getInit(expr, i); |
| ... | @@ -2026,8 +2054,8 @@ fn transInitListExprArray( | ... | @@ -2026,8 +2054,8 @@ fn transInitListExprArray( |
| 2026 | cat_tok = try appendToken(rp.c, .PlusPlus, "++"); | 2054 | cat_tok = try appendToken(rp.c, .PlusPlus, "++"); |
| 2027 | } | 2055 | } |
| 2028 | 2056 | ||
| 2029 | const dot_tok = try appendToken(rp.c, .Period, "."); | 2057 | const ty_node = try transCreateNodeArrayType(rp, loc, ZigClangQualType_getTypePtr(child_qt), 1); |
| 2030 | var filler_init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok); | 2058 | var filler_init_node = try transCreateNodeArrayInitializer(rp.c, ty_node); |
| 2031 | const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr); | 2059 | const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr); |
| 2032 | try filler_init_node.op.ArrayInitializer.push(try transExpr(rp, scope, filler_val_expr, .used, .r_value)); | 2060 | try filler_init_node.op.ArrayInitializer.push(try transExpr(rp, scope, filler_val_expr, .used, .r_value)); |
| 2033 | filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}"); | 2061 | filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}"); |
| ... | @@ -3878,11 +3906,11 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node { | ... | @@ -3878,11 +3906,11 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node { |
| 3878 | return &node.base; | 3906 | return &node.base; |
| 3879 | } | 3907 | } |
| 3880 | 3908 | ||
| 3881 | fn transCreateNodeContainerInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.Node.SuffixOp { | 3909 | fn transCreateNodeArrayInitializer(c: *Context, ty: *ast.Node) !*ast.Node.SuffixOp { |
| 3882 | _ = try appendToken(c, .LBrace, "{"); | 3910 | _ = try appendToken(c, .LBrace, "{"); |
| 3883 | const node = try c.a().create(ast.Node.SuffixOp); | 3911 | const node = try c.a().create(ast.Node.SuffixOp); |
| 3884 | node.* = ast.Node.SuffixOp{ | 3912 | node.* = ast.Node.SuffixOp{ |
| 3885 | .lhs = .{ .dot = dot_tok }, | 3913 | .lhs = .{ .node = ty }, |
| 3886 | .op = .{ | 3914 | .op = .{ |
| 3887 | .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()), | 3915 | .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()), |
| 3888 | }, | 3916 | }, |
test/run_translated_c.zig+16| ... | @@ -3,6 +3,22 @@ const tests = @import("tests.zig"); | ... | @@ -3,6 +3,22 @@ const tests = @import("tests.zig"); |
| 3 | const nl = std.cstr.line_sep; | 3 | const nl = std.cstr.line_sep; |
| 4 | 4 | ||
| 5 | pub fn addCases(cases: *tests.RunTranslatedCContext) void { | 5 | pub fn addCases(cases: *tests.RunTranslatedCContext) void { |
| 6 | cases.add("array initializer", | ||
| 7 | \\#include <stdlib.h> | ||
| 8 | \\int main(int argc, char **argv) { | ||
| 9 | \\ int a0[4] = {1}; | ||
| 10 | \\ int a1[4] = {1,2,3,4}; | ||
| 11 | \\ int s0 = 0, s1 = 0; | ||
| 12 | \\ for (int i = 0; i < 4; i++) { | ||
| 13 | \\ s0 += a0[i]; | ||
| 14 | \\ s1 += a1[i]; | ||
| 15 | \\ } | ||
| 16 | \\ if (s0 != 1) abort(); | ||
| 17 | \\ if (s1 != 10) abort(); | ||
| 18 | \\ return 0; | ||
| 19 | \\} | ||
| 20 | , ""); | ||
| 21 | |||
| 6 | cases.add("forward declarations", | 22 | cases.add("forward declarations", |
| 7 | \\#include <stdlib.h> | 23 | \\#include <stdlib.h> |
| 8 | \\int foo(int); | 24 | \\int foo(int); |
test/translate_c.zig+8-8| ... | @@ -18,7 +18,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -18,7 +18,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 18 | \\static const uuid_t UUID_NULL __attribute__ ((unused)) = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; | 18 | \\static const uuid_t UUID_NULL __attribute__ ((unused)) = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; |
| 19 | , &[_][]const u8{ | 19 | , &[_][]const u8{ |
| 20 | \\pub const uuid_t = [16]u8; | 20 | \\pub const uuid_t = [16]u8; |
| 21 | \\pub const UUID_NULL: uuid_t = .{ | 21 | \\pub const UUID_NULL: uuid_t = [16]u8{ |
| 22 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), | 22 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), |
| 23 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), | 23 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), |
| 24 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), | 24 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))), |
| ... | @@ -87,7 +87,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -87,7 +87,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 87 | \\ .x = @as(c_int, 1), | 87 | \\ .x = @as(c_int, 1), |
| 88 | \\}; | 88 | \\}; |
| 89 | \\pub export var ub: union_unnamed_1 = union_unnamed_1{ | 89 | \\pub export var ub: union_unnamed_1 = union_unnamed_1{ |
| 90 | \\ .c = .{ | 90 | \\ .c = [4]u8{ |
| 91 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 'a'))), | 91 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 'a'))), |
| 92 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 'b'))), | 92 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 'b'))), |
| 93 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 'b'))), | 93 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 'b'))), |
| ... | @@ -1118,12 +1118,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1118,12 +1118,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1118 | \\} | 1118 | \\} |
| 1119 | , &[_][]const u8{ | 1119 | , &[_][]const u8{ |
| 1120 | \\pub fn foo() callconv(.C) void { | 1120 | \\pub fn foo() callconv(.C) void { |
| 1121 | \\ var arr: [10]u8 = .{ | 1121 | \\ var arr: [10]u8 = [1]u8{ |
| 1122 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 1))), | 1122 | \\ @bitCast(u8, @truncate(i8, @as(c_int, 1))), |
| 1123 | \\ } ++ .{0} ** 9; | 1123 | \\ } ++ [1]u8{0} ** 9; |
| 1124 | \\ var arr1: [10][*c]u8 = .{ | 1124 | \\ var arr1: [10][*c]u8 = [1][*c]u8{ |
| 1125 | \\ null, | 1125 | \\ null, |
| 1126 | \\ } ++ .{null} ** 9; | 1126 | \\ } ++ [1][*c]u8{null} ** 9; |
| 1127 | \\} | 1127 | \\} |
| 1128 | }); | 1128 | }); |
| 1129 | 1129 | ||
| ... | @@ -1570,7 +1570,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1570,7 +1570,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1570 | cases.add("undefined array global", | 1570 | cases.add("undefined array global", |
| 1571 | \\int array[100] = {}; | 1571 | \\int array[100] = {}; |
| 1572 | , &[_][]const u8{ | 1572 | , &[_][]const u8{ |
| 1573 | \\pub export var array: [100]c_int = .{0} ** 100; | 1573 | \\pub export var array: [100]c_int = [1]c_int{0} ** 100; |
| 1574 | }); | 1574 | }); |
| 1575 | 1575 | ||
| 1576 | cases.add("restrict -> noalias", | 1576 | cases.add("restrict -> noalias", |
| ... | @@ -1904,7 +1904,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -1904,7 +1904,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 1904 | \\ return array[index]; | 1904 | \\ return array[index]; |
| 1905 | \\} | 1905 | \\} |
| 1906 | , &[_][]const u8{ | 1906 | , &[_][]const u8{ |
| 1907 | \\pub export var array: [100]c_int = .{0} ** 100; | 1907 | \\pub export var array: [100]c_int = [1]c_int{0} ** 100; |
| 1908 | \\pub export fn foo(arg_index: c_int) c_int { | 1908 | \\pub export fn foo(arg_index: c_int) c_int { |
| 1909 | \\ var index = arg_index; | 1909 | \\ var index = arg_index; |
| 1910 | \\ return array[@intCast(c_uint, index)]; | 1910 | \\ return array[@intCast(c_uint, index)]; |