authorgravatar for daniele.cocca@gmail.comDaniele Cocca <daniele.cocca@gmail.com> 2022-03-15 21:53:48+00:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-16 19:58:45-07:00
log312536540baf26728a56304811f63f01a7414b7a
tree5a5f168ec6001971e8cf3d2496fc6dec1d095355
parentd78b8c10b9b33a5b1a21e9fa981576fd408939e5

CBE: better handling of sentineled slices/arrays

Adds the sentinel element to the type name to avoid ambiguous declarations, and outputs the sentinel element (if needed) even in what would otherwise be empty arrays.

2 files changed, 25 insertions(+), 23 deletions(-)

src/codegen/c.zig+25-12
......@@ -616,27 +616,33 @@ pub const DeclGen = struct {
616616 .Array => {
617617 // First try specific tag representations for more efficiency.
618618 switch (val.tag()) {
619 .undef, .empty_struct_value, .empty_array => try writer.writeAll("{}"),
619 .undef, .empty_struct_value, .empty_array => {
620 try writer.writeByte('{');
621 const ai = ty.arrayInfo();
622 if (ai.sentinel) |s| {
623 try dg.renderValue(writer, ai.elem_type, s);
624 }
625 try writer.writeByte('}');
626 },
620627 else => {
621628 // Fall back to generic implementation.
622629 var arena = std.heap.ArenaAllocator.init(dg.module.gpa);
623630 defer arena.deinit();
624631 const arena_allocator = arena.allocator();
625632
626 try writer.writeAll("{");
633 try writer.writeByte('{');
634 const ai = ty.arrayInfo();
627635 var index: usize = 0;
628 const len = ty.arrayLen();
629 const elem_ty = ty.elemType();
630 while (index < len) : (index += 1) {
636 while (index < ai.len) : (index += 1) {
631637 if (index != 0) try writer.writeAll(",");
632638 const elem_val = try val.elemValue(arena_allocator, index);
633 try dg.renderValue(writer, elem_ty, elem_val);
639 try dg.renderValue(writer, ai.elem_type, elem_val);
634640 }
635 if (ty.sentinel()) |sentinel_val| {
641 if (ai.sentinel) |s| {
636642 if (index != 0) try writer.writeAll(",");
637 try dg.renderValue(writer, elem_ty, sentinel_val);
643 try dg.renderValue(writer, ai.elem_type, s);
638644 }
639 try writer.writeAll("}");
645 try writer.writeByte('}');
640646 },
641647 }
642648 },
......@@ -925,14 +931,21 @@ pub const DeclGen = struct {
925931 const ptr_alignment = Value.initTag(.abi_align_default);
926932 try dg.renderTypeAndName(bw, ptr_type, ptr_name, .Mut, ptr_alignment);
927933
934 const ptr_sentinel = ptr_type.ptrInfo().data.sentinel;
935 const child_type = t.childType();
936
928937 try bw.writeAll("; size_t len; } ");
929938 const name_index = buffer.items.len;
930 const elem_type = t.elemType();
931939 if (t.isConstPtr()) {
932 try bw.print("zig_L_{s};\n", .{typeToCIdentifier(elem_type)});
940 try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type)});
933941 } else {
934 try bw.print("zig_M_{s};\n", .{typeToCIdentifier(elem_type)});
942 try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type)});
943 }
944 if (ptr_sentinel) |s| {
945 try bw.writeAll("_s_");
946 try dg.renderValue(bw, child_type, s);
935947 }
948 try bw.writeAll(";\n");
936949
937950 const rendered = buffer.toOwnedSlice();
938951 errdefer dg.typedefs.allocator.free(rendered);
test/behavior/array.zig-11
......@@ -238,7 +238,6 @@ const Sub = struct { b: u8 };
238238const Str = struct { a: []Sub };
239239test "set global var array via slice embedded in struct" {
240240 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
241 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
242241 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
243242
244243 var s = Str{ .a = s_array[0..] };
......@@ -254,7 +253,6 @@ test "set global var array via slice embedded in struct" {
254253
255254test "read/write through global variable array of struct fields initialized via array mult" {
256255 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
257 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
258256 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
259257
260258 const S = struct {
......@@ -275,7 +273,6 @@ test "read/write through global variable array of struct fields initialized via
275273
276274test "implicit cast single-item pointer" {
277275 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
278 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
279276 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
280277
281278 try testImplicitCastSingleItemPtr();
......@@ -295,7 +292,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 {
295292
296293test "comptime evaluating function that takes array by value" {
297294 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
298 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
299295 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
300296
301297 const arr = [_]u8{ 1, 2 };
......@@ -307,7 +303,6 @@ test "comptime evaluating function that takes array by value" {
307303
308304test "runtime initialize array elem and then implicit cast to slice" {
309305 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
310 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
311306 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
312307
313308 var two: i32 = 2;
......@@ -317,7 +312,6 @@ test "runtime initialize array elem and then implicit cast to slice" {
317312
318313test "array literal as argument to function" {
319314 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
320 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
321315 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
322316
323317 const S = struct {
......@@ -345,7 +339,6 @@ test "array literal as argument to function" {
345339
346340test "double nested array to const slice cast in array literal" {
347341 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
348 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
349342 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
350343
351344 const S = struct {
......@@ -406,7 +399,6 @@ test "double nested array to const slice cast in array literal" {
406399
407400test "anonymous literal in array" {
408401 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
409 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
410402 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
411403
412404 const S = struct {
......@@ -431,7 +423,6 @@ test "anonymous literal in array" {
431423
432424test "access the null element of a null terminated array" {
433425 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
434 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
435426 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
436427
437428 const S = struct {
......@@ -448,7 +439,6 @@ test "access the null element of a null terminated array" {
448439
449440test "type deduction for array subscript expression" {
450441 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
451 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
452442 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
453443
454444 const S = struct {
......@@ -468,7 +458,6 @@ test "sentinel element count towards the ABI size calculation" {
468458 if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
469459 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
470460 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
471 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
472461 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
473462 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
474463