Skip to content

Commit f91ff9a

Browse files
jayschwaandrewrk
authored andcommitted
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
1 parent 5af5d87 commit f91ff9a

File tree

3 files changed

+121
-98
lines changed

3 files changed

+121
-98
lines changed

src/translate_c.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,6 +1229,14 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD
12291229
else
12301230
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+
12321240
if (is_anon) {
12331241
try c.decl_table.putNoClobber(c.gpa, @intFromPtr(field_decl.getCanonicalDecl()), field_name);
12341242
}
@@ -1237,6 +1245,7 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD
12371245
.name = field_name,
12381246
.type = field_type,
12391247
.alignment = alignment,
1248+
.default_value = default_value,
12401249
});
12411250
}
12421251

src/translate_c/ast.zig

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,7 @@ pub const Payload = struct {
576576
name: []const u8,
577577
type: Node,
578578
alignment: ?c_uint,
579+
default_value: ?Node,
579580
};
580581
};
581582

@@ -2095,34 +2096,47 @@ fn renderRecord(c: *Context, node: Node) !NodeIndex {
20952096
_ = try c.addToken(.colon, ":");
20962097
const type_expr = try renderNode(c, field.type);
20972098

2098-
const alignment = field.alignment orelse {
2099-
members[i] = try c.addNode(.{
2100-
.tag = .container_field_init,
2101-
.main_token = name_tok,
2102-
.data = .{
2103-
.lhs = type_expr,
2104-
.rhs = 0,
2105-
},
2099+
const align_expr = if (field.alignment) |alignment| blk: {
2100+
_ = try c.addToken(.keyword_align, "align");
2101+
_ = try c.addToken(.l_paren, "(");
2102+
const align_expr = try c.addNode(.{
2103+
.tag = .number_literal,
2104+
.main_token = try c.addTokenFmt(.number_literal, "{d}", .{alignment}),
2105+
.data = undefined,
21062106
});
2107-
_ = try c.addToken(.comma, ",");
2108-
continue;
2109-
};
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, ")");
2107+
_ = try c.addToken(.r_paren, ")");
2108+
break :blk align_expr;
2109+
} else 0;
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) .{
21202124
.tag = .container_field_align,
21212125
.main_token = name_tok,
21222126
.data = .{
21232127
.lhs = type_expr,
21242128
.rhs = align_expr,
21252129
},
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+
},
21262140
});
21272141
_ = try c.addToken(.comma, ",");
21282142
}

0 commit comments

Comments
 (0)