authorgravatar for jay@jayschwa.netJay Petacat <jay@jayschwa.net> 2023-09-18 14:05:44-06:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-09-18 23:09:47-07:00
logf91ff9a746ff97945dacc8114c073bd279f68f17
tree0f33d39d2a96f0d5bbd80114b16e6e17360710ce
parent5af5d87ad2227b6a7b5347c7217312ef8a83de12

translate-c: Struct fields default to zero value

C99 introduced designated initializers for structs. Omitted fields are implicitly initialized to zero. Some C APIs are designed with this in mind. Defaulting to zero values for translated struct fields permits Zig code to comfortably use such an API. Closes #8165

3 files changed, 121 insertions(+), 98 deletions(-)

src/translate_c.zig+9
...@@ -1229,6 +1229,14 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD...@@ -1229,6 +1229,14 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD
1229 else1229 else
1230 ClangAlignment.forField(c, field_decl, record_def).zigAlignment();1230 ClangAlignment.forField(c, field_decl, record_def).zigAlignment();
12311231
1232 // C99 introduced designated initializers for structs. Omitted fields are implicitly
1233 // initialized to zero. Some C APIs are designed with this in mind. Defaulting to zero
1234 // values for translated struct fields permits Zig code to comfortably use such an API.
1235 const default_value = if (record_decl.isStruct())
1236 try Tag.std_mem_zeroes.create(c.arena, field_type)
1237 else
1238 null;
1239
1232 if (is_anon) {1240 if (is_anon) {
1233 try c.decl_table.putNoClobber(c.gpa, @intFromPtr(field_decl.getCanonicalDecl()), field_name);1241 try c.decl_table.putNoClobber(c.gpa, @intFromPtr(field_decl.getCanonicalDecl()), field_name);
1234 }1242 }
...@@ -1237,6 +1245,7 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD...@@ -1237,6 +1245,7 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD
1237 .name = field_name,1245 .name = field_name,
1238 .type = field_type,1246 .type = field_type,
1239 .alignment = alignment,1247 .alignment = alignment,
1248 .default_value = default_value,
1240 });1249 });
1241 }1250 }
12421251
src/translate_c/ast.zig+34-20
...@@ -576,6 +576,7 @@ pub const Payload = struct {...@@ -576,6 +576,7 @@ pub const Payload = struct {
576 name: []const u8,576 name: []const u8,
577 type: Node,577 type: Node,
578 alignment: ?c_uint,578 alignment: ?c_uint,
579 default_value: ?Node,
579 };580 };
580 };581 };
581582
...@@ -2095,34 +2096,47 @@ fn renderRecord(c: *Context, node: Node) !NodeIndex {...@@ -2095,34 +2096,47 @@ fn renderRecord(c: *Context, node: Node) !NodeIndex {
2095 _ = try c.addToken(.colon, ":");2096 _ = try c.addToken(.colon, ":");
2096 const type_expr = try renderNode(c, field.type);2097 const type_expr = try renderNode(c, field.type);
20972098
2098 const alignment = field.alignment orelse {2099 const align_expr = if (field.alignment) |alignment| blk: {
2099 members[i] = try c.addNode(.{2100 _ = try c.addToken(.keyword_align, "align");
2100 .tag = .container_field_init,2101 _ = try c.addToken(.l_paren, "(");
2101 .main_token = name_tok,2102 const align_expr = try c.addNode(.{
2102 .data = .{2103 .tag = .number_literal,
2103 .lhs = type_expr,2104 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{alignment}),
2104 .rhs = 0,2105 .data = undefined,
2105 },
2106 });2106 });
2107 _ = try c.addToken(.comma, ",");2107 _ = try c.addToken(.r_paren, ")");
2108 continue;2108 break :blk align_expr;
2109 };2109 } else 0;
2110 _ = try c.addToken(.keyword_align, "align");
2111 _ = try c.addToken(.l_paren, "(");
2112 const align_expr = try c.addNode(.{
2113 .tag = .number_literal,
2114 .main_token = try c.addTokenFmt(.number_literal, "{d}", .{alignment}),
2115 .data = undefined,
2116 });
2117 _ = try c.addToken(.r_paren, ")");
21182110
2119 members[i] = try c.addNode(.{2111 const value_expr = if (field.default_value) |value| blk: {
2112 _ = try c.addToken(.equal, "=");
2113 break :blk try renderNode(c, value);
2114 } else 0;
2115
2116 members[i] = try c.addNode(if (align_expr == 0) .{
2117 .tag = .container_field_init,
2118 .main_token = name_tok,
2119 .data = .{
2120 .lhs = type_expr,
2121 .rhs = value_expr,
2122 },
2123 } else if (value_expr == 0) .{
2120 .tag = .container_field_align,2124 .tag = .container_field_align,
2121 .main_token = name_tok,2125 .main_token = name_tok,
2122 .data = .{2126 .data = .{
2123 .lhs = type_expr,2127 .lhs = type_expr,
2124 .rhs = align_expr,2128 .rhs = align_expr,
2125 },2129 },
2130 } else .{
2131 .tag = .container_field,
2132 .main_token = name_tok,
2133 .data = .{
2134 .lhs = type_expr,
2135 .rhs = try c.addExtra(std.zig.Ast.Node.ContainerField{
2136 .align_expr = align_expr,
2137 .value_expr = value_expr,
2138 }),
2139 },
2126 });2140 });
2127 _ = try c.addToken(.comma, ",");2141 _ = try c.addToken(.comma, ",");
2128 }2142 }
test/translate_c.zig+78-78
...@@ -98,8 +98,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -98,8 +98,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
98 ++ " " ++ default_enum_type ++98 ++ " " ++ default_enum_type ++
99 \\;99 \\;
100 \\pub const Bar = extern struct {100 \\pub const Bar = extern struct {
101 \\ a: c_int,101 \\ a: c_int = @import("std").mem.zeroes(c_int),
102 \\ b: c_int,102 \\ b: c_int = @import("std").mem.zeroes(c_int),
103 \\};103 \\};
104 });104 });
105105
...@@ -149,11 +149,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -149,11 +149,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
149 \\#define PTR void *149 \\#define PTR void *
150 , &[_][]const u8{150 , &[_][]const u8{
151 \\pub const struct_Bar_1 = extern struct {151 \\pub const struct_Bar_1 = extern struct {
152 \\ a: c_int,152 \\ a: c_int = @import("std").mem.zeroes(c_int),
153 \\};153 \\};
154 \\pub const struct_Foo = extern struct {154 \\pub const struct_Foo = extern struct {
155 \\ a: c_int,155 \\ a: c_int = @import("std").mem.zeroes(c_int),
156 \\ b: struct_Bar_1,156 \\ b: struct_Bar_1 = @import("std").mem.zeroes(struct_Bar_1),
157 \\};157 \\};
158 \\pub export var a: struct_Foo = struct_Foo{158 \\pub export var a: struct_Foo = struct_Foo{
159 \\ .a = 0,159 \\ .a = 0,
...@@ -183,9 +183,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -183,9 +183,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
183 , &[_][]const u8{183 , &[_][]const u8{
184 \\pub export fn foo() void {184 \\pub export fn foo() void {
185 \\ const struct_Foo = extern struct {185 \\ const struct_Foo = extern struct {
186 \\ A: c_int,186 \\ A: c_int = @import("std").mem.zeroes(c_int),
187 \\ B: c_int,187 \\ B: c_int = @import("std").mem.zeroes(c_int),
188 \\ C: c_int,188 \\ C: c_int = @import("std").mem.zeroes(c_int),
189 \\ };189 \\ };
190 \\ var a: struct_Foo = struct_Foo{190 \\ var a: struct_Foo = struct_Foo{
191 \\ .A = @as(c_int, 0),191 \\ .A = @as(c_int, 0),
...@@ -195,9 +195,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -195,9 +195,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
195 \\ _ = @TypeOf(a);195 \\ _ = @TypeOf(a);
196 \\ {196 \\ {
197 \\ const struct_Foo_1 = extern struct {197 \\ const struct_Foo_1 = extern struct {
198 \\ A: c_int,198 \\ A: c_int = @import("std").mem.zeroes(c_int),
199 \\ B: c_int,199 \\ B: c_int = @import("std").mem.zeroes(c_int),
200 \\ C: c_int,200 \\ C: c_int = @import("std").mem.zeroes(c_int),
201 \\ };201 \\ };
202 \\ var a_2: struct_Foo_1 = struct_Foo_1{202 \\ var a_2: struct_Foo_1 = struct_Foo_1{
203 \\ .A = @as(c_int, 0),203 \\ .A = @as(c_int, 0),
...@@ -286,7 +286,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -286,7 +286,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
286 \\source.h:1:9: warning: struct demoted to opaque type - unable to translate type of field foo286 \\source.h:1:9: warning: struct demoted to opaque type - unable to translate type of field foo
287 \\pub const Foo = opaque {};287 \\pub const Foo = opaque {};
288 \\pub const Bar = extern struct {288 \\pub const Bar = extern struct {
289 \\ bar: ?*Foo,289 \\ bar: ?*Foo = @import("std").mem.zeroes(?*Foo),
290 \\};290 \\};
291 });291 });
292292
...@@ -375,10 +375,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -375,10 +375,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
375 \\#define B A(0.f)375 \\#define B A(0.f)
376 , &[_][]const u8{376 , &[_][]const u8{
377 \\pub const struct_Color = extern struct {377 \\pub const struct_Color = extern struct {
378 \\ r: u8,378 \\ r: u8 = @import("std").mem.zeroes(u8),
379 \\ g: u8,379 \\ g: u8 = @import("std").mem.zeroes(u8),
380 \\ b: u8,380 \\ b: u8 = @import("std").mem.zeroes(u8),
381 \\ a: u8,381 \\ a: u8 = @import("std").mem.zeroes(u8),
382 \\};382 \\};
383 \\pub const Color = struct_Color;383 \\pub const Color = struct_Color;
384 ,384 ,
...@@ -389,14 +389,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -389,14 +389,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
389 \\pub const LIGHTGRAY = @import("std").mem.zeroInit(CLITERAL(Color), .{ @as(c_int, 200), @as(c_int, 200), @as(c_int, 200), @as(c_int, 255) });389 \\pub const LIGHTGRAY = @import("std").mem.zeroInit(CLITERAL(Color), .{ @as(c_int, 200), @as(c_int, 200), @as(c_int, 200), @as(c_int, 255) });
390 ,390 ,
391 \\pub const struct_boom_t = extern struct {391 \\pub const struct_boom_t = extern struct {
392 \\ i1: c_int,392 \\ i1: c_int = @import("std").mem.zeroes(c_int),
393 \\};393 \\};
394 \\pub const boom_t = struct_boom_t;394 \\pub const boom_t = struct_boom_t;
395 ,395 ,
396 \\pub const FOO = @import("std").mem.zeroInit(boom_t, .{@as(c_int, 1)});396 \\pub const FOO = @import("std").mem.zeroInit(boom_t, .{@as(c_int, 1)});
397 ,397 ,
398 \\pub const MyCStruct = extern struct {398 \\pub const MyCStruct = extern struct {
399 \\ x: f32,399 \\ x: f32 = @import("std").mem.zeroes(f32),
400 \\};400 \\};
401 ,401 ,
402 \\pub inline fn A(_x: anytype) MyCStruct {402 \\pub inline fn A(_x: anytype) MyCStruct {
...@@ -452,7 +452,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -452,7 +452,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
452 \\};452 \\};
453 , &[_][]const u8{453 , &[_][]const u8{
454 \\pub const struct_foo = extern struct {454 \\pub const struct_foo = extern struct {
455 \\ bar: c_short align(1),455 \\ bar: c_short align(1) = @import("std").mem.zeroes(c_short),
456 \\};456 \\};
457 });457 });
458458
...@@ -461,7 +461,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -461,7 +461,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
461 \\struct bar { int x; int y[0]; };461 \\struct bar { int x; int y[0]; };
462 , &[_][]const u8{462 , &[_][]const u8{
463 \\pub const struct_foo = extern struct {463 \\pub const struct_foo = extern struct {
464 \\ x: c_int align(4),464 \\ x: c_int align(4) = @import("std").mem.zeroes(c_int),
465 \\ pub fn y(self: anytype) @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int) {465 \\ pub fn y(self: anytype) @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int) {
466 \\ const Intermediate = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), u8);466 \\ const Intermediate = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), u8);
467 \\ const ReturnType = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int);467 \\ const ReturnType = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int);
...@@ -469,7 +469,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -469,7 +469,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
469 \\ }469 \\ }
470 \\};470 \\};
471 \\pub const struct_bar = extern struct {471 \\pub const struct_bar = extern struct {
472 \\ x: c_int align(4),472 \\ x: c_int align(4) = @import("std").mem.zeroes(c_int),
473 \\ pub fn y(self: anytype) @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int) {473 \\ pub fn y(self: anytype) @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int) {
474 \\ const Intermediate = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), u8);474 \\ const Intermediate = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), u8);
475 \\ const ReturnType = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int);475 \\ const ReturnType = @import("std").zig.c_translation.FlexibleArrayType(@TypeOf(self), c_int);
...@@ -545,7 +545,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -545,7 +545,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
545 \\source.h:4:8: warning: struct demoted to opaque type - unable to translate type of field abufused545 \\source.h:4:8: warning: struct demoted to opaque type - unable to translate type of field abufused
546 \\pub const struct_arcan_shmif_page = opaque {};546 \\pub const struct_arcan_shmif_page = opaque {};
547 \\pub const struct_arcan_shmif_cont = extern struct {547 \\pub const struct_arcan_shmif_cont = extern struct {
548 \\ addr: ?*struct_arcan_shmif_page,548 \\ addr: ?*struct_arcan_shmif_page = @import("std").mem.zeroes(?*struct_arcan_shmif_page),
549 \\};549 \\};
550 });550 });
551551
...@@ -562,10 +562,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -562,10 +562,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
562 \\pub const fnptr_ty = ?*const fn () callconv(.C) void;562 \\pub const fnptr_ty = ?*const fn () callconv(.C) void;
563 \\pub const fnptr_attr_ty = ?*const fn () callconv(.C) void;563 \\pub const fnptr_attr_ty = ?*const fn () callconv(.C) void;
564 \\pub const struct_foo = extern struct {564 \\pub const struct_foo = extern struct {
565 \\ foo: ?*const fn () callconv(.C) void,565 \\ foo: ?*const fn () callconv(.C) void = @import("std").mem.zeroes(?*const fn () callconv(.C) void),
566 \\ bar: ?*const fn () callconv(.C) void,566 \\ bar: ?*const fn () callconv(.C) void = @import("std").mem.zeroes(?*const fn () callconv(.C) void),
567 \\ baz: fnptr_ty,567 \\ baz: fnptr_ty = @import("std").mem.zeroes(fnptr_ty),
568 \\ qux: fnptr_attr_ty,568 \\ qux: fnptr_attr_ty = @import("std").mem.zeroes(fnptr_attr_ty),
569 \\};569 \\};
570 });570 });
571571
...@@ -624,14 +624,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -624,14 +624,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
624 \\void foo(outer *x) { x->y = x->x; }624 \\void foo(outer *x) { x->y = x->x; }
625 , &[_][]const u8{625 , &[_][]const u8{
626 \\const struct_unnamed_2 = extern struct {626 \\const struct_unnamed_2 = extern struct {
627 \\ y: c_int,627 \\ y: c_int = @import("std").mem.zeroes(c_int),
628 \\};628 \\};
629 \\const union_unnamed_1 = extern union {629 \\const union_unnamed_1 = extern union {
630 \\ x: u8,630 \\ x: u8,
631 \\ unnamed_0: struct_unnamed_2,631 \\ unnamed_0: struct_unnamed_2,
632 \\};632 \\};
633 \\pub const outer = extern struct {633 \\pub const outer = extern struct {
634 \\ unnamed_0: union_unnamed_1,634 \\ unnamed_0: union_unnamed_1 = @import("std").mem.zeroes(union_unnamed_1),
635 \\};635 \\};
636 \\pub export fn foo(arg_x: [*c]outer) void {636 \\pub export fn foo(arg_x: [*c]outer) void {
637 \\ var x = arg_x;637 \\ var x = arg_x;
...@@ -669,12 +669,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -669,12 +669,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
669 \\foo s3 = { 123 };669 \\foo s3 = { 123 };
670 , &[_][]const u8{670 , &[_][]const u8{
671 \\pub const foo = extern struct {671 \\pub const foo = extern struct {
672 \\ x: c_int,672 \\ x: c_int = @import("std").mem.zeroes(c_int),
673 \\};673 \\};
674 \\const struct_unnamed_1 = extern struct {674 \\const struct_unnamed_1 = extern struct {
675 \\ x: f64,675 \\ x: f64 = @import("std").mem.zeroes(f64),
676 \\ y: f64,676 \\ y: f64 = @import("std").mem.zeroes(f64),
677 \\ z: f64,677 \\ z: f64 = @import("std").mem.zeroes(f64),
678 \\};678 \\};
679 \\pub export var s0: struct_unnamed_1 = struct_unnamed_1{679 \\pub export var s0: struct_unnamed_1 = struct_unnamed_1{
680 \\ .x = 1.2,680 \\ .x = 1.2,
...@@ -682,12 +682,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -682,12 +682,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
682 \\ .z = 0,682 \\ .z = 0,
683 \\};683 \\};
684 \\const struct_unnamed_2 = extern struct {684 \\const struct_unnamed_2 = extern struct {
685 \\ sec: c_int,685 \\ sec: c_int = @import("std").mem.zeroes(c_int),
686 \\ min: c_int,686 \\ min: c_int = @import("std").mem.zeroes(c_int),
687 \\ hour: c_int,687 \\ hour: c_int = @import("std").mem.zeroes(c_int),
688 \\ day: c_int,688 \\ day: c_int = @import("std").mem.zeroes(c_int),
689 \\ mon: c_int,689 \\ mon: c_int = @import("std").mem.zeroes(c_int),
690 \\ year: c_int,690 \\ year: c_int = @import("std").mem.zeroes(c_int),
691 \\};691 \\};
692 \\pub export var s1: struct_unnamed_2 = struct_unnamed_2{692 \\pub export var s1: struct_unnamed_2 = struct_unnamed_2{
693 \\ .sec = @as(c_int, 30),693 \\ .sec = @as(c_int, 30),
...@@ -698,8 +698,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -698,8 +698,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
698 \\ .year = @as(c_int, 2014),698 \\ .year = @as(c_int, 2014),
699 \\};699 \\};
700 \\const struct_unnamed_3 = extern struct {700 \\const struct_unnamed_3 = extern struct {
701 \\ x: c_int,701 \\ x: c_int = @import("std").mem.zeroes(c_int),
702 \\ y: c_int,702 \\ y: c_int = @import("std").mem.zeroes(c_int),
703 \\};703 \\};
704 \\pub export var s2: struct_unnamed_3 = struct_unnamed_3{704 \\pub export var s2: struct_unnamed_3 = struct_unnamed_3{
705 \\ .x = @as(c_int, 1),705 \\ .x = @as(c_int, 1),
...@@ -730,9 +730,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -730,9 +730,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
730 \\struct {int x,y,z;} __attribute__((packed)) s0 = {1, 2};730 \\struct {int x,y,z;} __attribute__((packed)) s0 = {1, 2};
731 , &[_][]const u8{731 , &[_][]const u8{
732 \\const struct_unnamed_1 = extern struct {732 \\const struct_unnamed_1 = extern struct {
733 \\ x: c_int align(1),733 \\ x: c_int align(1) = @import("std").mem.zeroes(c_int),
734 \\ y: c_int align(1),734 \\ y: c_int align(1) = @import("std").mem.zeroes(c_int),
735 \\ z: c_int align(1),735 \\ z: c_int align(1) = @import("std").mem.zeroes(c_int),
736 \\};736 \\};
737 \\pub export var s0: struct_unnamed_1 = struct_unnamed_1{737 \\pub export var s0: struct_unnamed_1 = struct_unnamed_1{
738 \\ .x = @as(c_int, 1),738 \\ .x = @as(c_int, 1),
...@@ -977,8 +977,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -977,8 +977,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
977 , &[_][]const u8{977 , &[_][]const u8{
978 \\pub const lws_callback_function = fn () callconv(.C) void;978 \\pub const lws_callback_function = fn () callconv(.C) void;
979 \\pub const struct_Foo = extern struct {979 \\pub const struct_Foo = extern struct {
980 \\ func: ?*const fn () callconv(.C) void,980 \\ func: ?*const fn () callconv(.C) void = @import("std").mem.zeroes(?*const fn () callconv(.C) void),
981 \\ callback_http: ?*const lws_callback_function,981 \\ callback_http: ?*const lws_callback_function = @import("std").mem.zeroes(?*const lws_callback_function),
982 \\};982 \\};
983 });983 });
984984
...@@ -993,7 +993,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -993,7 +993,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
993 \\pub const struct_Foo = opaque {};993 \\pub const struct_Foo = opaque {};
994 ,994 ,
995 \\pub const struct_Bar = extern struct {995 \\pub const struct_Bar = extern struct {
996 \\ foo: ?*struct_Foo,996 \\ foo: ?*struct_Foo = @import("std").mem.zeroes(?*struct_Foo),
997 \\};997 \\};
998 });998 });
999999
...@@ -1025,13 +1025,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1025,13 +1025,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1025 \\};1025 \\};
1026 , &[_][]const u8{1026 , &[_][]const u8{
1027 \\pub const struct_Foo = extern struct {1027 \\pub const struct_Foo = extern struct {
1028 \\ a: [*c]Foo,1028 \\ a: [*c]Foo = @import("std").mem.zeroes([*c]Foo),
1029 \\};1029 \\};
1030 ,1030 ,
1031 \\pub const Foo = struct_Foo;1031 \\pub const Foo = struct_Foo;
1032 ,1032 ,
1033 \\pub const struct_Bar = extern struct {1033 \\pub const struct_Bar = extern struct {
1034 \\ a: [*c]Foo,1034 \\ a: [*c]Foo = @import("std").mem.zeroes([*c]Foo),
1035 \\};1035 \\};
1036 ,1036 ,
1037 \\pub const Bar = struct_Bar;1037 \\pub const Bar = struct_Bar;
...@@ -1044,8 +1044,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1044,8 +1044,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1044 \\};1044 \\};
1045 , &[_][]const u8{1045 , &[_][]const u8{
1046 \\const struct_Foo = extern struct {1046 \\const struct_Foo = extern struct {
1047 \\ x: c_int,1047 \\ x: c_int = @import("std").mem.zeroes(c_int),
1048 \\ y: [*c]u8,1048 \\ y: [*c]u8 = @import("std").mem.zeroes([*c]u8),
1049 \\};1049 \\};
1050 ,1050 ,
1051 \\pub const Foo = struct_Foo;1051 \\pub const Foo = struct_Foo;
...@@ -1057,7 +1057,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1057,7 +1057,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1057 \\};1057 \\};
1058 , &[_][]const u8{1058 , &[_][]const u8{
1059 \\pub const struct_Foo = extern struct {1059 \\pub const struct_Foo = extern struct {
1060 \\ derp: ?*const fn ([*c]struct_Foo) callconv(.C) void,1060 \\ derp: ?*const fn ([*c]struct_Foo) callconv(.C) void = @import("std").mem.zeroes(?*const fn ([*c]struct_Foo) callconv(.C) void),
1061 \\};1061 \\};
1062 ,1062 ,
1063 \\pub const Foo = struct_Foo;1063 \\pub const Foo = struct_Foo;
...@@ -1101,11 +1101,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1101,11 +1101,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1101 \\};1101 \\};
1102 , &[_][]const u8{1102 , &[_][]const u8{
1103 \\pub const struct_Bar = extern struct {1103 \\pub const struct_Bar = extern struct {
1104 \\ next: [*c]struct_Foo,1104 \\ next: [*c]struct_Foo = @import("std").mem.zeroes([*c]struct_Foo),
1105 \\};1105 \\};
1106 ,1106 ,
1107 \\pub const struct_Foo = extern struct {1107 \\pub const struct_Foo = extern struct {
1108 \\ next: [*c]struct_Bar,1108 \\ next: [*c]struct_Bar = @import("std").mem.zeroes([*c]struct_Bar),
1109 \\};1109 \\};
1110 });1110 });
11111111
...@@ -1121,7 +1121,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1121,7 +1121,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1121 \\};1121 \\};
1122 , &[_][]const u8{1122 , &[_][]const u8{
1123 \\pub const struct_comptime = extern struct {1123 \\pub const struct_comptime = extern struct {
1124 \\ @"defer": c_int,1124 \\ @"defer": c_int = @import("std").mem.zeroes(c_int),
1125 \\};1125 \\};
1126 ,1126 ,
1127 \\pub const @"comptime" = struct_comptime;1127 \\pub const @"comptime" = struct_comptime;
...@@ -1421,8 +1421,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1421,8 +1421,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1421 // even though the parent struct is1421 // even though the parent struct is
1422 // this is consistent with GCC docs1422 // this is consistent with GCC docs
1423 \\const struct_unnamed_1 = extern struct {1423 \\const struct_unnamed_1 = extern struct {
1424 \\ a: u8,1424 \\ a: u8 = @import("std").mem.zeroes(u8),
1425 \\ b: c_int,1425 \\ b: c_int = @import("std").mem.zeroes(c_int),
1426 \\};1426 \\};
1427 ,1427 ,
1428 \\pub const union_Foo = extern union {1428 \\pub const union_Foo = extern union {
...@@ -1448,8 +1448,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1448,8 +1448,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1448 // have an independent packed declaration on1448 // have an independent packed declaration on
1449 // the nested type (see GCC docs for details)1449 // the nested type (see GCC docs for details)
1450 \\const struct_unnamed_1 = extern struct {1450 \\const struct_unnamed_1 = extern struct {
1451 \\ a: u8 align(1),1451 \\ a: u8 align(1) = @import("std").mem.zeroes(u8),
1452 \\ b: c_int align(1),1452 \\ b: c_int align(1) = @import("std").mem.zeroes(c_int),
1453 \\};1453 \\};
1454 ,1454 ,
1455 \\pub const union_Foo = extern union {1455 \\pub const union_Foo = extern union {
...@@ -1905,8 +1905,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1905,8 +1905,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1905 ++ " " ++ default_enum_type ++1905 ++ " " ++ default_enum_type ++
1906 \\;1906 \\;
1907 \\pub const struct_Baz = extern struct {1907 \\pub const struct_Baz = extern struct {
1908 \\ l: enum_unnamed_2,1908 \\ l: enum_unnamed_2 = @import("std").mem.zeroes(enum_unnamed_2),
1909 \\ m: d,1909 \\ m: d = @import("std").mem.zeroes(d),
1910 \\};1910 \\};
1911 \\pub const n: c_int = 0;1911 \\pub const n: c_int = 0;
1912 \\pub const o: c_int = 1;1912 \\pub const o: c_int = 1;
...@@ -2010,7 +2010,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2010,7 +2010,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2010 \\pub const PFNGLCLEARPROC = ?*const fn (GLbitfield) callconv(.C) void;2010 \\pub const PFNGLCLEARPROC = ?*const fn (GLbitfield) callconv(.C) void;
2011 \\pub const OpenGLProc = ?*const fn () callconv(.C) void;2011 \\pub const OpenGLProc = ?*const fn () callconv(.C) void;
2012 \\const struct_unnamed_1 = extern struct {2012 \\const struct_unnamed_1 = extern struct {
2013 \\ Clear: PFNGLCLEARPROC,2013 \\ Clear: PFNGLCLEARPROC = @import("std").mem.zeroes(PFNGLCLEARPROC),
2014 \\};2014 \\};
2015 \\pub const union_OpenGLProcs = extern union {2015 \\pub const union_OpenGLProcs = extern union {
2016 \\ ptr: [1]OpenGLProc,2016 \\ ptr: [1]OpenGLProc,
...@@ -2362,10 +2362,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2362,10 +2362,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2362 \\};2362 \\};
2363 , &[_][]const u8{2363 , &[_][]const u8{
2364 \\pub const struct_Bar_1 = extern struct {2364 \\pub const struct_Bar_1 = extern struct {
2365 \\ b: c_int,2365 \\ b: c_int = @import("std").mem.zeroes(c_int),
2366 \\};2366 \\};
2367 \\pub const struct_Foo = extern struct {2367 \\pub const struct_Foo = extern struct {
2368 \\ c: struct_Bar_1,2368 \\ c: struct_Bar_1 = @import("std").mem.zeroes(struct_Bar_1),
2369 \\};2369 \\};
2370 });2370 });
2371 }2371 }
...@@ -2576,8 +2576,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2576,8 +2576,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2576 \\void func(struct Foo *a, enum Bar **b);2576 \\void func(struct Foo *a, enum Bar **b);
2577 , &[_][]const u8{2577 , &[_][]const u8{
2578 \\pub const struct_Foo = extern struct {2578 \\pub const struct_Foo = extern struct {
2579 \\ x: c_int,2579 \\ x: c_int = @import("std").mem.zeroes(c_int),
2580 \\ y: c_int,2580 \\ y: c_int = @import("std").mem.zeroes(c_int),
2581 \\};2581 \\};
2582 \\pub const BarA: c_int = 0;2582 \\pub const BarA: c_int = 0;
2583 \\pub const BarB: c_int = 1;2583 \\pub const BarB: c_int = 1;
...@@ -2694,7 +2694,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2694,7 +2694,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2694 \\}2694 \\}
2695 , &[_][]const u8{2695 , &[_][]const u8{
2696 \\pub const struct_Foo = extern struct {2696 \\pub const struct_Foo = extern struct {
2697 \\ b: c_int,2697 \\ b: c_int = @import("std").mem.zeroes(c_int),
2698 \\};2698 \\};
2699 \\pub extern var a: struct_Foo;2699 \\pub extern var a: struct_Foo;
2700 \\pub export var b: f32 = 2.0;2700 \\pub export var b: f32 = 2.0;
...@@ -3604,12 +3604,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3604,12 +3604,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3604 \\} ONENAMEWITHSTRUCT;3604 \\} ONENAMEWITHSTRUCT;
3605 , &[_][]const u8{3605 , &[_][]const u8{
3606 \\pub const struct_NAMED = extern struct {3606 \\pub const struct_NAMED = extern struct {
3607 \\ name: c_long,3607 \\ name: c_long = @import("std").mem.zeroes(c_long),
3608 \\};3608 \\};
3609 \\pub const NAMED = struct_NAMED;3609 \\pub const NAMED = struct_NAMED;
3610 \\pub const struct_ONENAMEWITHSTRUCT = extern struct {3610 \\pub const struct_ONENAMEWITHSTRUCT = extern struct {
3611 \\ unnamed_0: struct_NAMED,3611 \\ unnamed_0: struct_NAMED = = @import("std").mem.zeroes(struct_NAMED),
3612 \\ b: c_long,3612 \\ b: c_long = @import("std").mem.zeroes(c_long),
3613 \\};3613 \\};
3614 });3614 });
3615 } else {3615 } else {
...@@ -3626,11 +3626,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3626,11 +3626,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3626 \\} ONENAMEWITHSTRUCT;3626 \\} ONENAMEWITHSTRUCT;
3627 , &[_][]const u8{3627 , &[_][]const u8{
3628 \\pub const struct_NAMED = extern struct {3628 \\pub const struct_NAMED = extern struct {
3629 \\ name: c_long,3629 \\ name: c_long = @import("std").mem.zeroes(c_long),
3630 \\};3630 \\};
3631 \\pub const NAMED = struct_NAMED;3631 \\pub const NAMED = struct_NAMED;
3632 \\pub const struct_ONENAMEWITHSTRUCT = extern struct {3632 \\pub const struct_ONENAMEWITHSTRUCT = extern struct {
3633 \\ b: c_long,3633 \\ b: c_long = @import("std").mem.zeroes(c_long),
3634 \\};3634 \\};
3635 });3635 });
3636 }3636 }
...@@ -3645,11 +3645,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3645,11 +3645,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3645 , &[_][]const u8{3645 , &[_][]const u8{
3646 \\const struct_unnamed_1 = extern struct {};3646 \\const struct_unnamed_1 = extern struct {};
3647 \\pub const struct_a = extern struct {3647 \\pub const struct_a = extern struct {
3648 \\ unnamed_0: struct_unnamed_1,3648 \\ unnamed_0: struct_unnamed_1 = @import("std").mem.zeroes(struct_unnamed_1),
3649 \\};3649 \\};
3650 \\const struct_unnamed_2 = extern struct {};3650 \\const struct_unnamed_2 = extern struct {};
3651 \\pub const struct_b = extern struct {3651 \\pub const struct_b = extern struct {
3652 \\ unnamed_0: struct_unnamed_2,3652 \\ unnamed_0: struct_unnamed_2 = @import("std").mem.zeroes(struct_unnamed_2),
3653 \\};3653 \\};
3654 });3654 });
36553655
...@@ -3783,8 +3783,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3783,8 +3783,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3783 \\pub const struct_inner = opaque {};3783 \\pub const struct_inner = opaque {};
3784 ,3784 ,
3785 \\pub const struct_outer = extern struct {3785 \\pub const struct_outer = extern struct {
3786 \\ thing: c_int,3786 \\ thing: c_int = @import("std").mem.zeroes(c_int),
3787 \\ sub_struct: struct_inner,3787 \\ sub_struct: struct_inner = @import("std").mem.zeroes(struct_inner),
3788 \\};3788 \\};
3789 ,3789 ,
3790 \\warning: unable to translate function, demoted to extern3790 \\warning: unable to translate function, demoted to extern
...@@ -3812,8 +3812,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3812,8 +3812,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3812 \\}3812 \\}
3813 , &[_][]const u8{3813 , &[_][]const u8{
3814 \\pub const struct_FOO = extern struct {3814 \\pub const struct_FOO = extern struct {
3815 \\ x: c_int,3815 \\ x: c_int = @import("std").mem.zeroes(c_int),
3816 \\ y: c_int,3816 \\ y: c_int = @import("std").mem.zeroes(c_int),
3817 \\};3817 \\};
3818 \\pub export fn bar() c_int {3818 \\pub export fn bar() c_int {
3819 \\ const foo = struct {3819 \\ const foo = struct {
...@@ -4143,7 +4143,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -4143,7 +4143,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
4143 \\const char *struct_foo = "hello world";4143 \\const char *struct_foo = "hello world";
4144 , &[_][]const u8{4144 , &[_][]const u8{
4145 \\pub const struct_foo_1 = extern struct {4145 \\pub const struct_foo_1 = extern struct {
4146 \\ x: c_int,4146 \\ x: c_int = @import("std").mem.zeroes(c_int),
4147 \\};4147 \\};
4148 ,4148 ,
4149 \\pub const foo = struct_foo_1;4149 \\pub const foo = struct_foo_1;