authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-29 10:57:09-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-29 10:57:09-05:00
logabe6c2d5859461900e0ceeb98800987413b3355a
tree20e6a66ab6211ca62035b9c2a9773059a16b248c
parentf66ac9a5e704d9900d9e21cb482d7487a02e7b34

allow packed containers in extern functions


3 files changed, 22 insertions(+), 6 deletions(-)

src/analyze.cpp+3-3
...@@ -1242,16 +1242,16 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {...@@ -1242,16 +1242,16 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
1242 case TypeTableEntryIdPointer:1242 case TypeTableEntryIdPointer:
1243 return type_allowed_in_extern(g, type_entry->data.pointer.child_type);1243 return type_allowed_in_extern(g, type_entry->data.pointer.child_type);
1244 case TypeTableEntryIdStruct:1244 case TypeTableEntryIdStruct:
1245 return type_entry->data.structure.layout == ContainerLayoutExtern;1245 return type_entry->data.structure.layout == ContainerLayoutExtern || type_entry->data.structure.layout == ContainerLayoutPacked;
1246 case TypeTableEntryIdMaybe:1246 case TypeTableEntryIdMaybe:
1247 {1247 {
1248 TypeTableEntry *child_type = type_entry->data.maybe.child_type;1248 TypeTableEntry *child_type = type_entry->data.maybe.child_type;
1249 return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;1249 return child_type->id == TypeTableEntryIdPointer || child_type->id == TypeTableEntryIdFn;
1250 }1250 }
1251 case TypeTableEntryIdEnum:1251 case TypeTableEntryIdEnum:
1252 return type_entry->data.enumeration.layout == ContainerLayoutExtern;1252 return type_entry->data.enumeration.layout == ContainerLayoutExtern || type_entry->data.enumeration.layout == ContainerLayoutPacked;
1253 case TypeTableEntryIdUnion:1253 case TypeTableEntryIdUnion:
1254 return type_entry->data.unionation.layout == ContainerLayoutExtern;1254 return type_entry->data.unionation.layout == ContainerLayoutExtern || type_entry->data.unionation.layout == ContainerLayoutPacked;
1255 }1255 }
1256 zig_unreachable();1256 zig_unreachable();
1257}1257}
test/cases/misc.zig+16
...@@ -617,3 +617,19 @@ test "cold function" {...@@ -617,3 +617,19 @@ test "cold function" {
617fn thisIsAColdFn() void {617fn thisIsAColdFn() void {
618 @setCold(true);618 @setCold(true);
619}619}
620
621
622const PackedStruct = packed struct { a: u8, b: u8, };
623const PackedUnion = packed union { a: u8, b: u32, };
624const PackedEnum = packed enum { A, B, };
625
626test "packed struct, enum, union parameters in extern function" {
627 testPackedStuff(
628 PackedStruct{.a = 1, .b = 2},
629 PackedUnion{.a = 1},
630 PackedEnum.A,
631 );
632}
633
634export fn testPackedStuff(a: &const PackedStruct, b: &const PackedUnion, c: PackedEnum) void {
635}
test/compile_errors.zig+3-3
...@@ -5,12 +5,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -5,12 +5,12 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
5 \\export fn foo() boid {}5 \\export fn foo() boid {}
6 , ".tmp_source.zig:1:17: error: use of undeclared identifier 'boid'");6 , ".tmp_source.zig:1:17: error: use of undeclared identifier 'boid'");
77
8 cases.add("function with non-extern enum parameter",8 cases.add("function with non-extern non-packed enum parameter",
9 \\const Foo = enum { A, B, C };9 \\const Foo = enum { A, B, C };
10 \\export fn entry(foo: Foo) void { }10 \\export fn entry(foo: Foo) void { }
11 , ".tmp_source.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");11 , ".tmp_source.zig:2:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
1212
13 cases.add("function with non-extern struct parameter",13 cases.add("function with non-extern non-packed struct parameter",
14 \\const Foo = struct {14 \\const Foo = struct {
15 \\ A: i32,15 \\ A: i32,
16 \\ B: f32,16 \\ B: f32,
...@@ -19,7 +19,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {...@@ -19,7 +19,7 @@ pub fn addCases(cases: &tests.CompileErrorContext) void {
19 \\export fn entry(foo: Foo) void { }19 \\export fn entry(foo: Foo) void { }
20 , ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");20 , ".tmp_source.zig:6:22: error: parameter of type 'Foo' not allowed in function with calling convention 'ccc'");
2121
22 cases.add("function with non-extern union parameter",22 cases.add("function with non-extern non-packed union parameter",
23 \\const Foo = union {23 \\const Foo = union {
24 \\ A: i32,24 \\ A: i32,
25 \\ B: f32,25 \\ B: f32,