authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-10 02:04:37-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-10-25 05:11:29-04:00
logfeb8f81cd9d8df282d57441422dc70cee079a993
tree2e09fea550b83287ea836b9d029495852cd4bb2f
parent5eafc10bf41451fb694f324dcaefe5c458e1ca3a

cbe: canonicalize types that have the same C type when emitting typedefs


4 files changed, 25 insertions(+), 33 deletions(-)

src/codegen/c.zig+25-28
......@@ -1067,6 +1067,8 @@ pub const DeclGen = struct {
10671067 }
10681068
10691069 fn renderSliceTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1070 std.debug.assert(t.sentinel() == null); // expected canonical type
1071
10701072 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
10711073 defer buffer.deinit();
10721074 const bw = buffer.writer();
......@@ -1078,22 +1080,12 @@ pub const DeclGen = struct {
10781080 const ptr_name = CValue{ .bytes = "ptr" };
10791081 try dg.renderTypeAndName(bw, ptr_type, ptr_name, .Mut, 0);
10801082
1081 const ptr_sentinel = ptr_type.ptrInfo().data.sentinel;
1082 const child_type = t.childType();
1083
10841083 try bw.writeAll("; size_t len; } ");
10851084 const name_begin = buffer.items.len;
10861085 try bw.print("zig_{c}_{}", .{
10871086 @as(u8, if (t.isConstPtr()) 'L' else 'M'),
1088 typeToCIdentifier(child_type, dg.module),
1087 typeToCIdentifier(t.childType(), dg.module),
10891088 });
1090 if (ptr_sentinel) |s| {
1091 var sentinel_buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1092 defer sentinel_buffer.deinit();
1093
1094 try dg.renderValue(sentinel_buffer.writer(), child_type, s, .Identifier);
1095 try bw.print("_s_{}", .{fmtIdent(sentinel_buffer.items)});
1096 }
10971089 const name_end = buffer.items.len;
10981090 try bw.writeAll(";\n");
10991091
......@@ -1351,28 +1343,21 @@ pub const DeclGen = struct {
13511343 }
13521344
13531345 fn renderArrayTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1346 const info = t.arrayInfo();
1347 std.debug.assert(info.sentinel == null); // expected canonical type
1348
13541349 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
13551350 defer buffer.deinit();
13561351 const bw = buffer.writer();
13571352
1358 const elem_type = t.elemType();
1359
13601353 try bw.writeAll("typedef ");
1361 try dg.renderType(bw, elem_type);
1354 try dg.renderType(bw, info.elem_type);
13621355
13631356 const name_begin = buffer.items.len + " ".len;
1364 try bw.print(" zig_A_{}_{d}", .{ typeToCIdentifier(elem_type, dg.module), t.arrayLen() });
1365 if (t.sentinel()) |s| {
1366 var sentinel_buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1367 defer sentinel_buffer.deinit();
1368
1369 try dg.renderValue(sentinel_buffer.writer(), elem_type, s, .Identifier);
1370 try bw.print("_s_{}", .{fmtIdent(sentinel_buffer.items)});
1371 }
1357 try bw.print(" zig_A_{}_{d}", .{ typeToCIdentifier(info.elem_type, dg.module), info.len });
13721358 const name_end = buffer.items.len;
13731359
1374 const c_len = t.arrayLenIncludingSentinel();
1375 try bw.print("[{d}];\n", .{if (c_len > 0) c_len else 1});
1360 try bw.print("[{d}];\n", .{if (info.len > 0) info.len else 1});
13761361
13771362 const rendered = buffer.toOwnedSlice();
13781363 errdefer dg.typedefs.allocator.free(rendered);
......@@ -1509,8 +1494,14 @@ pub const DeclGen = struct {
15091494 },
15101495 .Pointer => {
15111496 if (t.isSlice()) {
1512 const name = dg.getTypedefName(t) orelse
1513 try dg.renderSliceTypedef(t);
1497 var slice_ty_pl = Type.Payload.ElemType{
1498 .base = .{ .tag = if (t.ptrIsMutable()) .mut_slice else .const_slice },
1499 .data = t.childType(),
1500 };
1501 const slice_ty = Type.initPayload(&slice_ty_pl.base);
1502
1503 const name = dg.getTypedefName(slice_ty) orelse
1504 try dg.renderSliceTypedef(slice_ty);
15141505
15151506 return w.writeAll(name);
15161507 }
......@@ -1541,8 +1532,14 @@ pub const DeclGen = struct {
15411532 return w.writeAll(" *");
15421533 },
15431534 .Array => {
1544 const name = dg.getTypedefName(t) orelse
1545 try dg.renderArrayTypedef(t);
1535 var array_ty_pl = Type.Payload.Array{ .base = .{ .tag = .array }, .data = .{
1536 .len = t.arrayLenIncludingSentinel(),
1537 .elem_type = t.childType(),
1538 } };
1539 const array_ty = Type.initPayload(&array_ty_pl.base);
1540
1541 const name = dg.getTypedefName(array_ty) orelse
1542 try dg.renderArrayTypedef(array_ty);
15461543
15471544 return w.writeAll(name);
15481545 },
test/behavior/align.zig-2
......@@ -221,7 +221,6 @@ fn fnWithAlignedStack() i32 {
221221}
222222
223223test "implicitly decreasing slice alignment" {
224 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
225224 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
226225
227226 const a: u32 align(4) = 3;
......@@ -244,7 +243,6 @@ fn testBytesAlign(b: u8) !void {
244243}
245244
246245test "@alignCast slices" {
247 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
248246 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
249247 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
250248
test/behavior/for.zig-1
......@@ -195,7 +195,6 @@ test "for on slice with allowzero ptr" {
195195 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
196196 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
197197 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
198 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
199198
200199 const S = struct {
201200 fn doTheTest(slice: []const u8) !void {
test/behavior/slice.zig-2
......@@ -319,7 +319,6 @@ test "empty array to slice" {
319319
320320test "@ptrCast slice to pointer" {
321321 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
322 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
323322
324323 const S = struct {
325324 fn doTheTest() !void {
......@@ -335,7 +334,6 @@ test "@ptrCast slice to pointer" {
335334}
336335
337336test "slice syntax resulting in pointer-to-array" {
338 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
339337 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
340338 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
341339 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO