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 {...@@ -1067,6 +1067,8 @@ pub const DeclGen = struct {
1067 }1067 }
10681068
1069 fn renderSliceTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1069 fn renderSliceTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
1070 std.debug.assert(t.sentinel() == null); // expected canonical type
1071
1070 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1072 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1071 defer buffer.deinit();1073 defer buffer.deinit();
1072 const bw = buffer.writer();1074 const bw = buffer.writer();
...@@ -1078,22 +1080,12 @@ pub const DeclGen = struct {...@@ -1078,22 +1080,12 @@ pub const DeclGen = struct {
1078 const ptr_name = CValue{ .bytes = "ptr" };1080 const ptr_name = CValue{ .bytes = "ptr" };
1079 try dg.renderTypeAndName(bw, ptr_type, ptr_name, .Mut, 0);1081 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
1084 try bw.writeAll("; size_t len; } ");1083 try bw.writeAll("; size_t len; } ");
1085 const name_begin = buffer.items.len;1084 const name_begin = buffer.items.len;
1086 try bw.print("zig_{c}_{}", .{1085 try bw.print("zig_{c}_{}", .{
1087 @as(u8, if (t.isConstPtr()) 'L' else 'M'),1086 @as(u8, if (t.isConstPtr()) 'L' else 'M'),
1088 typeToCIdentifier(child_type, dg.module),1087 typeToCIdentifier(t.childType(), dg.module),
1089 });1088 });
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 }
1097 const name_end = buffer.items.len;1089 const name_end = buffer.items.len;
1098 try bw.writeAll(";\n");1090 try bw.writeAll(";\n");
10991091
...@@ -1351,28 +1343,21 @@ pub const DeclGen = struct {...@@ -1351,28 +1343,21 @@ pub const DeclGen = struct {
1351 }1343 }
13521344
1353 fn renderArrayTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {1345 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
1354 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);1349 var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
1355 defer buffer.deinit();1350 defer buffer.deinit();
1356 const bw = buffer.writer();1351 const bw = buffer.writer();
13571352
1358 const elem_type = t.elemType();
1359
1360 try bw.writeAll("typedef ");1353 try bw.writeAll("typedef ");
1361 try dg.renderType(bw, elem_type);1354 try dg.renderType(bw, info.elem_type);
13621355
1363 const name_begin = buffer.items.len + " ".len;1356 const name_begin = buffer.items.len + " ".len;
1364 try bw.print(" zig_A_{}_{d}", .{ typeToCIdentifier(elem_type, dg.module), t.arrayLen() });1357 try bw.print(" zig_A_{}_{d}", .{ typeToCIdentifier(info.elem_type, dg.module), info.len });
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 }
1372 const name_end = buffer.items.len;1358 const name_end = buffer.items.len;
13731359
1374 const c_len = t.arrayLenIncludingSentinel();1360 try bw.print("[{d}];\n", .{if (info.len > 0) info.len else 1});
1375 try bw.print("[{d}];\n", .{if (c_len > 0) c_len else 1});
13761361
1377 const rendered = buffer.toOwnedSlice();1362 const rendered = buffer.toOwnedSlice();
1378 errdefer dg.typedefs.allocator.free(rendered);1363 errdefer dg.typedefs.allocator.free(rendered);
...@@ -1509,8 +1494,14 @@ pub const DeclGen = struct {...@@ -1509,8 +1494,14 @@ pub const DeclGen = struct {
1509 },1494 },
1510 .Pointer => {1495 .Pointer => {
1511 if (t.isSlice()) {1496 if (t.isSlice()) {
1512 const name = dg.getTypedefName(t) orelse1497 var slice_ty_pl = Type.Payload.ElemType{
1513 try dg.renderSliceTypedef(t);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
1515 return w.writeAll(name);1506 return w.writeAll(name);
1516 }1507 }
...@@ -1541,8 +1532,14 @@ pub const DeclGen = struct {...@@ -1541,8 +1532,14 @@ pub const DeclGen = struct {
1541 return w.writeAll(" *");1532 return w.writeAll(" *");
1542 },1533 },
1543 .Array => {1534 .Array => {
1544 const name = dg.getTypedefName(t) orelse1535 var array_ty_pl = Type.Payload.Array{ .base = .{ .tag = .array }, .data = .{
1545 try dg.renderArrayTypedef(t);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
1547 return w.writeAll(name);1544 return w.writeAll(name);
1548 },1545 },
test/behavior/align.zig-2
...@@ -221,7 +221,6 @@ fn fnWithAlignedStack() i32 {...@@ -221,7 +221,6 @@ fn fnWithAlignedStack() i32 {
221}221}
222222
223test "implicitly decreasing slice alignment" {223test "implicitly decreasing slice alignment" {
224 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
225 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;224 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
226225
227 const a: u32 align(4) = 3;226 const a: u32 align(4) = 3;
...@@ -244,7 +243,6 @@ fn testBytesAlign(b: u8) !void {...@@ -244,7 +243,6 @@ fn testBytesAlign(b: u8) !void {
244}243}
245244
246test "@alignCast slices" {245test "@alignCast slices" {
247 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
248 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;246 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
249 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;247 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" {...@@ -195,7 +195,6 @@ test "for on slice with allowzero ptr" {
195 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO195 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
196 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO196 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
197 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO197 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
198 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
199198
200 const S = struct {199 const S = struct {
201 fn doTheTest(slice: []const u8) !void {200 fn doTheTest(slice: []const u8) !void {
test/behavior/slice.zig-2
...@@ -319,7 +319,6 @@ test "empty array to slice" {...@@ -319,7 +319,6 @@ test "empty array to slice" {
319319
320test "@ptrCast slice to pointer" {320test "@ptrCast slice to pointer" {
321 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;321 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
322 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
323322
324 const S = struct {323 const S = struct {
325 fn doTheTest() !void {324 fn doTheTest() !void {
...@@ -335,7 +334,6 @@ test "@ptrCast slice to pointer" {...@@ -335,7 +334,6 @@ test "@ptrCast slice to pointer" {
335}334}
336335
337test "slice syntax resulting in pointer-to-array" {336test "slice syntax resulting in pointer-to-array" {
338 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
339 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO337 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
340 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO338 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
341 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO339 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO