mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
CBE: add support for tuples
Also promote tests that are now passing.
This commit is contained in:
parent
085e122e29
commit
6fdca525de
@ -1000,6 +1000,46 @@ pub const DeclGen = struct {
|
||||
return name;
|
||||
}
|
||||
|
||||
fn renderTupleTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
|
||||
const tuple = t.tupleFields();
|
||||
|
||||
var buffer = std.ArrayList(u8).init(dg.typedefs.allocator);
|
||||
defer buffer.deinit();
|
||||
const writer = buffer.writer();
|
||||
|
||||
try buffer.appendSlice("typedef struct {\n");
|
||||
{
|
||||
for (tuple.types) |field_ty, i| {
|
||||
const val = tuple.values[i];
|
||||
if (val.tag() != .unreachable_value) continue;
|
||||
|
||||
var name = std.ArrayList(u8).init(dg.gpa);
|
||||
defer name.deinit();
|
||||
try name.writer().print("field_{d}", .{i});
|
||||
|
||||
try buffer.append(' ');
|
||||
try dg.renderTypeAndName(writer, field_ty, .{ .bytes = name.items }, .Mut, Value.initTag(.abi_align_default));
|
||||
try buffer.appendSlice(";\n");
|
||||
}
|
||||
}
|
||||
try buffer.appendSlice("} ");
|
||||
|
||||
const name_start = buffer.items.len;
|
||||
try writer.print("zig_T_{};\n", .{typeToCIdentifier(t)});
|
||||
|
||||
const rendered = buffer.toOwnedSlice();
|
||||
errdefer dg.typedefs.allocator.free(rendered);
|
||||
const name = rendered[name_start .. rendered.len - 2];
|
||||
|
||||
try dg.typedefs.ensureUnusedCapacity(1);
|
||||
dg.typedefs.putAssumeCapacityNoClobber(
|
||||
try t.copy(dg.typedefs_arena),
|
||||
.{ .name = name, .rendered = rendered },
|
||||
);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
fn renderUnionTypedef(dg: *DeclGen, t: Type) error{ OutOfMemory, AnalysisFail }![]const u8 {
|
||||
const union_ty = t.cast(Type.Payload.Union).?.data;
|
||||
const fqn = try union_ty.getFullyQualifiedName(dg.typedefs.allocator);
|
||||
@ -1276,7 +1316,9 @@ pub const DeclGen = struct {
|
||||
return w.writeAll(name);
|
||||
},
|
||||
.Struct => {
|
||||
const name = dg.getTypedefName(t) orelse
|
||||
const name = dg.getTypedefName(t) orelse if (t.isTuple())
|
||||
try dg.renderTupleTypedef(t)
|
||||
else
|
||||
try dg.renderStructTypedef(t);
|
||||
|
||||
return w.writeAll(name);
|
||||
@ -3116,6 +3158,8 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
|
||||
var field_name: []const u8 = undefined;
|
||||
var field_val_ty: Type = undefined;
|
||||
|
||||
var buf = std.ArrayList(u8).init(f.object.dg.gpa);
|
||||
defer buf.deinit();
|
||||
switch (struct_ty.tag()) {
|
||||
.@"struct" => {
|
||||
const fields = struct_ty.structFields();
|
||||
@ -3127,6 +3171,14 @@ fn structFieldPtr(f: *Function, inst: Air.Inst.Index, struct_ptr_ty: Type, struc
|
||||
field_name = fields.keys()[index];
|
||||
field_val_ty = fields.values()[index].ty;
|
||||
},
|
||||
.tuple => {
|
||||
const tuple = struct_ty.tupleFields();
|
||||
if (tuple.values[index].tag() != .unreachable_value) return CValue.none;
|
||||
|
||||
try buf.writer().print("field_{d}", .{index});
|
||||
field_name = buf.items;
|
||||
field_val_ty = tuple.types[index];
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
const payload = if (struct_ty.tag() == .union_tagged) "payload." else "";
|
||||
@ -3149,9 +3201,18 @@ fn airStructFieldVal(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
const writer = f.object.writer();
|
||||
const struct_byval = try f.resolveInst(extra.struct_operand);
|
||||
const struct_ty = f.air.typeOf(extra.struct_operand);
|
||||
var buf = std.ArrayList(u8).init(f.object.dg.gpa);
|
||||
defer buf.deinit();
|
||||
const field_name = switch (struct_ty.tag()) {
|
||||
.@"struct" => struct_ty.structFields().keys()[extra.field_index],
|
||||
.@"union", .union_tagged => struct_ty.unionFields().keys()[extra.field_index],
|
||||
.tuple => blk: {
|
||||
const tuple = struct_ty.tupleFields();
|
||||
if (tuple.values[extra.field_index].tag() != .unreachable_value) return CValue.none;
|
||||
|
||||
try buf.writer().print("field_{d}", .{extra.field_index});
|
||||
break :blk buf.items;
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
const payload = if (struct_ty.tag() == .union_tagged) "payload." else "";
|
||||
@ -3652,11 +3713,25 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
|
||||
const writer = f.object.writer();
|
||||
const local = try f.allocLocal(inst_ty, .Const);
|
||||
try writer.writeAll(" = ");
|
||||
try writer.writeAll(" = {");
|
||||
switch (vector_ty.zigTypeTag()) {
|
||||
.Struct => {
|
||||
const tuple = vector_ty.tupleFields();
|
||||
var i: usize = 0;
|
||||
for (elements) |elem, elem_index| {
|
||||
if (tuple.values[elem_index].tag() != .unreachable_value) continue;
|
||||
|
||||
_ = elements;
|
||||
_ = local;
|
||||
return f.fail("TODO: C backend: implement airAggregateInit", .{});
|
||||
const value = try f.resolveInst(elem);
|
||||
if (i != 0) try writer.writeAll(", ");
|
||||
try f.writeCValue(writer, value);
|
||||
i += 1;
|
||||
}
|
||||
},
|
||||
else => |tag| return f.fail("TODO: C backend: implement airAggregateInit for type {s}", .{@tagName(tag)}),
|
||||
}
|
||||
try writer.writeAll("};\n");
|
||||
|
||||
return local;
|
||||
}
|
||||
|
||||
fn airUnionInit(f: *Function, inst: Air.Inst.Index) !CValue {
|
||||
|
||||
@ -145,6 +145,7 @@ test {
|
||||
{
|
||||
// Tests that pass for stage1, llvm backend, C backend
|
||||
_ = @import("behavior/bugs/421.zig");
|
||||
_ = @import("behavior/bugs/3779.zig");
|
||||
_ = @import("behavior/bugs/9584.zig");
|
||||
_ = @import("behavior/cast_int.zig");
|
||||
_ = @import("behavior/eval.zig");
|
||||
@ -161,7 +162,6 @@ test {
|
||||
_ = @import("behavior/saturating_arithmetic.zig");
|
||||
_ = @import("behavior/widening.zig");
|
||||
_ = @import("behavior/bugs/2114.zig");
|
||||
_ = @import("behavior/bugs/3779.zig");
|
||||
_ = @import("behavior/bugs/10147.zig");
|
||||
_ = @import("behavior/shuffle.zig");
|
||||
|
||||
|
||||
@ -5,7 +5,6 @@ const expect = testing.expect;
|
||||
|
||||
test "tuple concatenation" {
|
||||
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
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
@ -50,7 +49,6 @@ test "tuple multiplication" {
|
||||
|
||||
test "more tuple concatenation" {
|
||||
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_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
@ -128,7 +126,6 @@ test "tuple initializer for var" {
|
||||
}
|
||||
|
||||
test "array-like initializer for tuple types" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user