authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-30 16:12:23-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2020-01-30 16:12:23-05:00
log13f782426660f49eb6ee7561ecee9237c22b4dc9
tree34ca1e3a1b3fcf2fb9e7f1c83e7645ba1e8263c1
parent58c97b3561c39036c2db1875d5a1b5125dd580ef
parent979c69d6b27a38e89ac85eb7db4f0c03c19433d5
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #4326 from LemonBoy/fix-4181

Generate compilable code for array inits

3 files changed, 58 insertions(+), 14 deletions(-)

src-self-hosted/translate_c.zig+34-6
......@@ -1991,6 +1991,29 @@ fn transInitListExprRecord(
19911991 return &init_node.base;
19921992}
19931993
1994fn 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
19942017fn transInitListExprArray(
19952018 rp: RestorePoint,
19962019 scope: *Scope,
......@@ -2011,8 +2034,13 @@ fn transInitListExprArray(
20112034 var init_node: *ast.Node.SuffixOp = undefined;
20122035 var cat_tok: ast.TokenIndex = undefined;
20132036 if (init_count != 0) {
2014 const dot_tok = try appendToken(rp.c, .Period, ".");
2015 init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok);
2037 const ty_node = try transCreateNodeArrayType(
2038 rp,
2039 loc,
2040 ZigClangQualType_getTypePtr(child_qt),
2041 init_count,
2042 );
2043 init_node = try transCreateNodeArrayInitializer(rp.c, ty_node);
20162044 var i: c_uint = 0;
20172045 while (i < init_count) : (i += 1) {
20182046 const elem_expr = ZigClangInitListExpr_getInit(expr, i);
......@@ -2026,8 +2054,8 @@ fn transInitListExprArray(
20262054 cat_tok = try appendToken(rp.c, .PlusPlus, "++");
20272055 }
20282056
2029 const dot_tok = try appendToken(rp.c, .Period, ".");
2030 var filler_init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok);
2057 const ty_node = try transCreateNodeArrayType(rp, loc, ZigClangQualType_getTypePtr(child_qt), 1);
2058 var filler_init_node = try transCreateNodeArrayInitializer(rp.c, ty_node);
20312059 const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);
20322060 try filler_init_node.op.ArrayInitializer.push(try transExpr(rp, scope, filler_val_expr, .used, .r_value));
20332061 filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
......@@ -3878,11 +3906,11 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {
38783906 return &node.base;
38793907}
38803908
3881fn transCreateNodeContainerInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.Node.SuffixOp {
3909fn transCreateNodeArrayInitializer(c: *Context, ty: *ast.Node) !*ast.Node.SuffixOp {
38823910 _ = try appendToken(c, .LBrace, "{");
38833911 const node = try c.a().create(ast.Node.SuffixOp);
38843912 node.* = ast.Node.SuffixOp{
3885 .lhs = .{ .dot = dot_tok },
3913 .lhs = .{ .node = ty },
38863914 .op = .{
38873915 .ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
38883916 },
test/run_translated_c.zig+16
......@@ -3,6 +3,22 @@ const tests = @import("tests.zig");
33const nl = std.cstr.line_sep;
44
55pub 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
622 cases.add("forward declarations",
723 \\#include <stdlib.h>
824 \\int foo(int);
test/translate_c.zig+8-8
......@@ -18,7 +18,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1818 \\static const uuid_t UUID_NULL __attribute__ ((unused)) = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
1919 , &[_][]const u8{
2020 \\pub const uuid_t = [16]u8;
21 \\pub const UUID_NULL: uuid_t = .{
21 \\pub const UUID_NULL: uuid_t = [16]u8{
2222 \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
2323 \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
2424 \\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
......@@ -87,7 +87,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
8787 \\ .x = @as(c_int, 1),
8888 \\};
8989 \\pub export var ub: union_unnamed_1 = union_unnamed_1{
90 \\ .c = .{
90 \\ .c = [4]u8{
9191 \\ @bitCast(u8, @truncate(i8, @as(c_int, 'a'))),
9292 \\ @bitCast(u8, @truncate(i8, @as(c_int, 'b'))),
9393 \\ @bitCast(u8, @truncate(i8, @as(c_int, 'b'))),
......@@ -1118,12 +1118,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
11181118 \\}
11191119 , &[_][]const u8{
11201120 \\pub fn foo() callconv(.C) void {
1121 \\ var arr: [10]u8 = .{
1121 \\ var arr: [10]u8 = [1]u8{
11221122 \\ @bitCast(u8, @truncate(i8, @as(c_int, 1))),
1123 \\ } ++ .{0} ** 9;
1124 \\ var arr1: [10][*c]u8 = .{
1123 \\ } ++ [1]u8{0} ** 9;
1124 \\ var arr1: [10][*c]u8 = [1][*c]u8{
11251125 \\ null,
1126 \\ } ++ .{null} ** 9;
1126 \\ } ++ [1][*c]u8{null} ** 9;
11271127 \\}
11281128 });
11291129
......@@ -1570,7 +1570,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15701570 cases.add("undefined array global",
15711571 \\int array[100] = {};
15721572 , &[_][]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;
15741574 });
15751575
15761576 cases.add("restrict -> noalias",
......@@ -1904,7 +1904,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
19041904 \\ return array[index];
19051905 \\}
19061906 , &[_][]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;
19081908 \\pub export fn foo(arg_index: c_int) c_int {
19091909 \\ var index = arg_index;
19101910 \\ return array[@intCast(c_uint, index)];