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
2092320923 switch (val->type->data.structure.layout) {
2092420924 case ContainerLayoutAuto:
2092520925 zig_unreachable();
20926 case ContainerLayoutExtern:
20927 zig_panic("TODO buf_write_value_bytes extern struct");
20926 case ContainerLayoutExtern: {
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 }
2092820939 case ContainerLayoutPacked: {
2092920940 size_t src_field_count = val->type->data.structure.src_field_count;
2093020941 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
2097920990 offset += big_int_byte_count;
2098020991 gen_i += 1;
2098120992 }
20993 return;
2098220994 }
2098320995 }
20984 return;
2098520996 case ZigTypeIdOptional:
2098620997 zig_panic("TODO buf_write_value_bytes maybe type");
2098720998 case ZigTypeIdErrorUnion:
test/stage1/behavior/bitcast.zig+28
......@@ -66,3 +66,31 @@ test "@bitCast packed structs at runtime and comptime" {
6666 S.doTheTest();
6767 comptime S.doTheTest();
6868}
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}