authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-21 08:46:43-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-02-21 08:46:43-05:00
logdb31c2524df4352593128aaceaa0b085ef8bb674
treee748e614ff6c1718bf4580616d1f9c032926a621
parent3ee9d06cbdb6bcaf561e7215c4c103c7ad65a72d
signature Commit is signed but in an unrecognized format.

extern structs support comptime bitcasting


2 files changed, 42 insertions(+), 3 deletions(-)

src/ir.cpp+14-3
...@@ -20923,8 +20923,19 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -20923,8 +20923,19 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
20923 switch (val->type->data.structure.layout) {20923 switch (val->type->data.structure.layout) {
20924 case ContainerLayoutAuto:20924 case ContainerLayoutAuto:
20925 zig_unreachable();20925 zig_unreachable();
20926 case ContainerLayoutExtern:20926 case ContainerLayoutExtern: {
20927 zig_panic("TODO buf_write_value_bytes extern struct");20927 size_t src_field_count = val->type->data.structure.src_field_count;
20928 for (size_t field_i = 0; field_i < src_field_count; field_i += 1) {
20929 TypeStructField *type_field = &val->type->data.structure.fields[field_i];
20930 if (type_field->gen_index == SIZE_MAX)
20931 continue;
20932 ConstExprValue *field_val = &val->data.x_struct.fields[field_i];
20933 size_t offset = LLVMOffsetOfElement(codegen->target_data_ref, val->type->type_ref,
20934 type_field->gen_index);
20935 buf_write_value_bytes(codegen, buf + offset, field_val);
20936 }
20937 return;
20938 }
20928 case ContainerLayoutPacked: {20939 case ContainerLayoutPacked: {
20929 size_t src_field_count = val->type->data.structure.src_field_count;20940 size_t src_field_count = val->type->data.structure.src_field_count;
20930 size_t gen_field_count = val->type->data.structure.gen_field_count;20941 size_t gen_field_count = val->type->data.structure.gen_field_count;
...@@ -20979,9 +20990,9 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue...@@ -20979,9 +20990,9 @@ static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue
20979 offset += big_int_byte_count;20990 offset += big_int_byte_count;
20980 gen_i += 1;20991 gen_i += 1;
20981 }20992 }
20993 return;
20982 }20994 }
20983 }20995 }
20984 return;
20985 case ZigTypeIdOptional:20996 case ZigTypeIdOptional:
20986 zig_panic("TODO buf_write_value_bytes maybe type");20997 zig_panic("TODO buf_write_value_bytes maybe type");
20987 case ZigTypeIdErrorUnion:20998 case ZigTypeIdErrorUnion:
test/stage1/behavior/bitcast.zig+28
...@@ -66,3 +66,31 @@ test "@bitCast packed structs at runtime and comptime" {...@@ -66,3 +66,31 @@ test "@bitCast packed structs at runtime and comptime" {
66 S.doTheTest();66 S.doTheTest();
67 comptime S.doTheTest();67 comptime S.doTheTest();
68}68}
69
70test "@bitCast extern structs at runtime and comptime" {
71 const Full = extern struct {
72 number: u16,
73 };
74 const TwoHalves = extern struct {
75 half1: u8,
76 half2: u8,
77 };
78 const S = struct {
79 fn doTheTest() void {
80 var full = Full{ .number = 0x1234 };
81 var two_halves = @bitCast(TwoHalves, full);
82 switch (builtin.endian) {
83 builtin.Endian.Big => {
84 expect(two_halves.half1 == 0x12);
85 expect(two_halves.half2 == 0x34);
86 },
87 builtin.Endian.Little => {
88 expect(two_halves.half1 == 0x34);
89 expect(two_halves.half2 == 0x12);
90 },
91 }
92 }
93 };
94 S.doTheTest();
95 comptime S.doTheTest();
96}