diff --git a/src/codegen/c.zig b/src/codegen/c.zig index 358e7354dd..c0c2031116 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -616,27 +616,33 @@ pub const DeclGen = struct { .Array => { // First try specific tag representations for more efficiency. switch (val.tag()) { - .undef, .empty_struct_value, .empty_array => try writer.writeAll("{}"), + .undef, .empty_struct_value, .empty_array => { + try writer.writeByte('{'); + const ai = ty.arrayInfo(); + if (ai.sentinel) |s| { + try dg.renderValue(writer, ai.elem_type, s); + } + try writer.writeByte('}'); + }, else => { // Fall back to generic implementation. var arena = std.heap.ArenaAllocator.init(dg.module.gpa); defer arena.deinit(); const arena_allocator = arena.allocator(); - try writer.writeAll("{"); + try writer.writeByte('{'); + const ai = ty.arrayInfo(); var index: usize = 0; - const len = ty.arrayLen(); - const elem_ty = ty.elemType(); - while (index < len) : (index += 1) { + while (index < ai.len) : (index += 1) { if (index != 0) try writer.writeAll(","); const elem_val = try val.elemValue(arena_allocator, index); - try dg.renderValue(writer, elem_ty, elem_val); + try dg.renderValue(writer, ai.elem_type, elem_val); } - if (ty.sentinel()) |sentinel_val| { + if (ai.sentinel) |s| { if (index != 0) try writer.writeAll(","); - try dg.renderValue(writer, elem_ty, sentinel_val); + try dg.renderValue(writer, ai.elem_type, s); } - try writer.writeAll("}"); + try writer.writeByte('}'); }, } }, @@ -925,14 +931,21 @@ pub const DeclGen = struct { const ptr_alignment = Value.initTag(.abi_align_default); try dg.renderTypeAndName(bw, ptr_type, ptr_name, .Mut, ptr_alignment); + const ptr_sentinel = ptr_type.ptrInfo().data.sentinel; + const child_type = t.childType(); + try bw.writeAll("; size_t len; } "); const name_index = buffer.items.len; - const elem_type = t.elemType(); if (t.isConstPtr()) { - try bw.print("zig_L_{s};\n", .{typeToCIdentifier(elem_type)}); + try bw.print("zig_L_{s}", .{typeToCIdentifier(child_type)}); } else { - try bw.print("zig_M_{s};\n", .{typeToCIdentifier(elem_type)}); + try bw.print("zig_M_{s}", .{typeToCIdentifier(child_type)}); } + if (ptr_sentinel) |s| { + try bw.writeAll("_s_"); + try dg.renderValue(bw, child_type, s); + } + try bw.writeAll(";\n"); const rendered = buffer.toOwnedSlice(); errdefer dg.typedefs.allocator.free(rendered); diff --git a/test/behavior/array.zig b/test/behavior/array.zig index 098d3d343c..4561db792f 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -238,7 +238,6 @@ const Sub = struct { b: u8 }; const Str = struct { a: []Sub }; test "set global var array via slice embedded in struct" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var s = Str{ .a = s_array[0..] }; @@ -254,7 +253,6 @@ test "set global var array via slice embedded in struct" { test "read/write through global variable array of struct fields initialized via array mult" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -275,7 +273,6 @@ test "read/write through global variable array of struct fields initialized via test "implicit cast single-item pointer" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO try testImplicitCastSingleItemPtr(); @@ -295,7 +292,6 @@ fn testArrayByValAtComptime(b: [2]u8) u8 { test "comptime evaluating function that takes array by value" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const arr = [_]u8{ 1, 2 }; @@ -307,7 +303,6 @@ test "comptime evaluating function that takes array by value" { test "runtime initialize array elem and then implicit cast to slice" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO var two: i32 = 2; @@ -317,7 +312,6 @@ test "runtime initialize array elem and then implicit cast to slice" { test "array literal as argument to function" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -345,7 +339,6 @@ test "array literal as argument to function" { test "double nested array to const slice cast in array literal" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -406,7 +399,6 @@ test "double nested array to const slice cast in array literal" { test "anonymous literal in array" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -431,7 +423,6 @@ test "anonymous literal in array" { test "access the null element of a null terminated array" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -448,7 +439,6 @@ test "access the null element of a null terminated array" { test "type deduction for array subscript expression" { if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO const S = struct { @@ -468,7 +458,6 @@ test "sentinel element count towards the ABI size calculation" { if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO - if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO