Skip to content

Generate compilable code for array inits #4326

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 34 additions & 6 deletions src-self-hosted/translate_c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1991,6 +1991,29 @@ fn transInitListExprRecord(
return &init_node.base;
}

fn transCreateNodeArrayType(
rp: RestorePoint,
source_loc: ZigClangSourceLocation,
ty: *const ZigClangType,
len: var,
) TransError!*ast.Node {
var node = try transCreateNodePrefixOp(
rp.c,
.{
.ArrayType = .{
.len_expr = undefined,
.sentinel = null,
},
},
.LBracket,
"[",
);
node.op.ArrayType.len_expr = try transCreateNodeInt(rp.c, len);
_ = try appendToken(rp.c, .RBracket, "]");
node.rhs = try transType(rp, ty, source_loc);
return &node.base;
}

fn transInitListExprArray(
rp: RestorePoint,
scope: *Scope,
Expand All @@ -2011,8 +2034,13 @@ fn transInitListExprArray(
var init_node: *ast.Node.SuffixOp = undefined;
var cat_tok: ast.TokenIndex = undefined;
if (init_count != 0) {
const dot_tok = try appendToken(rp.c, .Period, ".");
init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok);
const ty_node = try transCreateNodeArrayType(
rp,
loc,
ZigClangQualType_getTypePtr(child_qt),
init_count,
);
init_node = try transCreateNodeArrayInitializer(rp.c, ty_node);
var i: c_uint = 0;
while (i < init_count) : (i += 1) {
const elem_expr = ZigClangInitListExpr_getInit(expr, i);
Expand All @@ -2026,8 +2054,8 @@ fn transInitListExprArray(
cat_tok = try appendToken(rp.c, .PlusPlus, "++");
}

const dot_tok = try appendToken(rp.c, .Period, ".");
var filler_init_node = try transCreateNodeContainerInitializer(rp.c, dot_tok);
const ty_node = try transCreateNodeArrayType(rp, loc, ZigClangQualType_getTypePtr(child_qt), 1);
var filler_init_node = try transCreateNodeArrayInitializer(rp.c, ty_node);
const filler_val_expr = ZigClangInitListExpr_getArrayFiller(expr);
try filler_init_node.op.ArrayInitializer.push(try transExpr(rp, scope, filler_val_expr, .used, .r_value));
filler_init_node.rtoken = try appendToken(rp.c, .RBrace, "}");
Expand Down Expand Up @@ -3878,11 +3906,11 @@ fn transCreateNodeBoolLiteral(c: *Context, value: bool) !*ast.Node {
return &node.base;
}

fn transCreateNodeContainerInitializer(c: *Context, dot_tok: ast.TokenIndex) !*ast.Node.SuffixOp {
fn transCreateNodeArrayInitializer(c: *Context, ty: *ast.Node) !*ast.Node.SuffixOp {
_ = try appendToken(c, .LBrace, "{");
const node = try c.a().create(ast.Node.SuffixOp);
node.* = ast.Node.SuffixOp{
.lhs = .{ .dot = dot_tok },
.lhs = .{ .node = ty },
.op = .{
.ArrayInitializer = ast.Node.SuffixOp.Op.InitList.init(c.a()),
},
Expand Down
16 changes: 16 additions & 0 deletions test/run_translated_c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@ const tests = @import("tests.zig");
const nl = std.cstr.line_sep;

pub fn addCases(cases: *tests.RunTranslatedCContext) void {
cases.add("array initializer",
\\#include <stdlib.h>
\\int main(int argc, char **argv) {
\\ int a0[4] = {1};
\\ int a1[4] = {1,2,3,4};
\\ int s0 = 0, s1 = 0;
\\ for (int i = 0; i < 4; i++) {
\\ s0 += a0[i];
\\ s1 += a1[i];
\\ }
\\ if (s0 != 1) abort();
\\ if (s1 != 10) abort();
\\ return 0;
\\}
, "");

cases.add("forward declarations",
\\#include <stdlib.h>
\\int foo(int);
Expand Down
16 changes: 8 additions & 8 deletions test/translate_c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\static const uuid_t UUID_NULL __attribute__ ((unused)) = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
, &[_][]const u8{
\\pub const uuid_t = [16]u8;
\\pub const UUID_NULL: uuid_t = .{
\\pub const UUID_NULL: uuid_t = [16]u8{
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
\\ @bitCast(u8, @truncate(i8, @as(c_int, 0))),
Expand Down Expand Up @@ -87,7 +87,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ .x = @as(c_int, 1),
\\};
\\pub export var ub: union_unnamed_1 = union_unnamed_1{
\\ .c = .{
\\ .c = [4]u8{
\\ @bitCast(u8, @truncate(i8, @as(c_int, 'a'))),
\\ @bitCast(u8, @truncate(i8, @as(c_int, 'b'))),
\\ @bitCast(u8, @truncate(i8, @as(c_int, 'b'))),
Expand Down Expand Up @@ -1118,12 +1118,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\}
, &[_][]const u8{
\\pub fn foo() callconv(.C) void {
\\ var arr: [10]u8 = .{
\\ var arr: [10]u8 = [1]u8{
\\ @bitCast(u8, @truncate(i8, @as(c_int, 1))),
\\ } ++ .{0} ** 9;
\\ var arr1: [10][*c]u8 = .{
\\ } ++ [1]u8{0} ** 9;
\\ var arr1: [10][*c]u8 = [1][*c]u8{
\\ null,
\\ } ++ .{null} ** 9;
\\ } ++ [1][*c]u8{null} ** 9;
\\}
});

Expand Down Expand Up @@ -1570,7 +1570,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
cases.add("undefined array global",
\\int array[100] = {};
, &[_][]const u8{
\\pub export var array: [100]c_int = .{0} ** 100;
\\pub export var array: [100]c_int = [1]c_int{0} ** 100;
});

cases.add("restrict -> noalias",
Expand Down Expand Up @@ -1904,7 +1904,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\ return array[index];
\\}
, &[_][]const u8{
\\pub export var array: [100]c_int = .{0} ** 100;
\\pub export var array: [100]c_int = [1]c_int{0} ** 100;
\\pub export fn foo(arg_index: c_int) c_int {
\\ var index = arg_index;
\\ return array[@intCast(c_uint, index)];
Expand Down