authorgravatar for jhc@dismail.deJimmi Holst Christensen <jhc@dismail.de> 2018-07-18 17:00:42+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-18 11:00:42-04:00
logfd3a41dadc92e7b69b409af5f747004996465032
tree6a14bc1520587f6c255329815ec3d9b62e884c35
parentc393a399fb4b463f095a8510595263759fd82cd6

Allow pointers to anything in extern/exported declarations (#1258)

* type_allowed_in_extern accepts all ptr not size 0 * Generate correct headers for none extern structs/unions/enums

3 files changed, 95 insertions(+), 37 deletions(-)

src/analyze.cpp+3-1
...@@ -1454,7 +1454,9 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {...@@ -1454,7 +1454,9 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
1454 case TypeTableEntryIdFn:1454 case TypeTableEntryIdFn:
1455 return type_entry->data.fn.fn_type_id.cc == CallingConventionC;1455 return type_entry->data.fn.fn_type_id.cc == CallingConventionC;
1456 case TypeTableEntryIdPointer:1456 case TypeTableEntryIdPointer:
1457 return type_allowed_in_extern(g, type_entry->data.pointer.child_type);1457 if (type_size(g, type_entry) == 0)
1458 return false;
1459 return true;
1458 case TypeTableEntryIdStruct:1460 case TypeTableEntryIdStruct:
1459 return type_entry->data.structure.layout == ContainerLayoutExtern || type_entry->data.structure.layout == ContainerLayoutPacked;1461 return type_entry->data.structure.layout == ContainerLayoutExtern || type_entry->data.structure.layout == ContainerLayoutPacked;
1460 case TypeTableEntryIdOptional:1462 case TypeTableEntryIdOptional:
src/codegen.cpp+45-36
...@@ -7508,51 +7508,60 @@ static void gen_h_file(CodeGen *g) {...@@ -7508,51 +7508,60 @@ static void gen_h_file(CodeGen *g) {
7508 case TypeTableEntryIdPromise:7508 case TypeTableEntryIdPromise:
7509 zig_unreachable();7509 zig_unreachable();
7510 case TypeTableEntryIdEnum:7510 case TypeTableEntryIdEnum:
7511 assert(type_entry->data.enumeration.layout == ContainerLayoutExtern);7511 if (type_entry->data.enumeration.layout == ContainerLayoutExtern) {
7512 fprintf(out_h, "enum %s {\n", buf_ptr(&type_entry->name));7512 fprintf(out_h, "enum %s {\n", buf_ptr(&type_entry->name));
7513 for (uint32_t field_i = 0; field_i < type_entry->data.enumeration.src_field_count; field_i += 1) {7513 for (uint32_t field_i = 0; field_i < type_entry->data.enumeration.src_field_count; field_i += 1) {
7514 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i];7514 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i];
7515 Buf *value_buf = buf_alloc();7515 Buf *value_buf = buf_alloc();
7516 bigint_append_buf(value_buf, &enum_field->value, 10);7516 bigint_append_buf(value_buf, &enum_field->value, 10);
7517 fprintf(out_h, " %s = %s", buf_ptr(enum_field->name), buf_ptr(value_buf));7517 fprintf(out_h, " %s = %s", buf_ptr(enum_field->name), buf_ptr(value_buf));
7518 if (field_i != type_entry->data.enumeration.src_field_count - 1) {7518 if (field_i != type_entry->data.enumeration.src_field_count - 1) {
7519 fprintf(out_h, ",");7519 fprintf(out_h, ",");
7520 }
7521 fprintf(out_h, "\n");
7520 }7522 }
7521 fprintf(out_h, "\n");7523 fprintf(out_h, "};\n\n");
7524 } else {
7525 fprintf(out_h, "enum %s;\n", buf_ptr(&type_entry->name));
7522 }7526 }
7523 fprintf(out_h, "};\n\n");
7524 break;7527 break;
7525 case TypeTableEntryIdStruct:7528 case TypeTableEntryIdStruct:
7526 assert(type_entry->data.structure.layout == ContainerLayoutExtern);7529 if (type_entry->data.structure.layout == ContainerLayoutExtern) {
7527 fprintf(out_h, "struct %s {\n", buf_ptr(&type_entry->name));7530 fprintf(out_h, "struct %s {\n", buf_ptr(&type_entry->name));
7528 for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) {7531 for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) {
7529 TypeStructField *struct_field = &type_entry->data.structure.fields[field_i];7532 TypeStructField *struct_field = &type_entry->data.structure.fields[field_i];
75307533
7531 Buf *type_name_buf = buf_alloc();7534 Buf *type_name_buf = buf_alloc();
7532 get_c_type(g, gen_h, struct_field->type_entry, type_name_buf);7535 get_c_type(g, gen_h, struct_field->type_entry, type_name_buf);
75337536
7534 if (struct_field->type_entry->id == TypeTableEntryIdArray) {7537 if (struct_field->type_entry->id == TypeTableEntryIdArray) {
7535 fprintf(out_h, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf),7538 fprintf(out_h, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf),
7536 buf_ptr(struct_field->name),7539 buf_ptr(struct_field->name),
7537 struct_field->type_entry->data.array.len);7540 struct_field->type_entry->data.array.len);
7538 } else {7541 } else {
7539 fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name));7542 fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name));
7540 }7543 }
75417544
7545 }
7546 fprintf(out_h, "};\n\n");
7547 } else {
7548 fprintf(out_h, "struct %s;\n", buf_ptr(&type_entry->name));
7542 }7549 }
7543 fprintf(out_h, "};\n\n");
7544 break;7550 break;
7545 case TypeTableEntryIdUnion:7551 case TypeTableEntryIdUnion:
7546 assert(type_entry->data.unionation.layout == ContainerLayoutExtern);7552 if (type_entry->data.unionation.layout == ContainerLayoutExtern) {
7547 fprintf(out_h, "union %s {\n", buf_ptr(&type_entry->name));7553 fprintf(out_h, "union %s {\n", buf_ptr(&type_entry->name));
7548 for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) {7554 for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) {
7549 TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i];7555 TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i];
75507556
7551 Buf *type_name_buf = buf_alloc();7557 Buf *type_name_buf = buf_alloc();
7552 get_c_type(g, gen_h, union_field->type_entry, type_name_buf);7558 get_c_type(g, gen_h, union_field->type_entry, type_name_buf);
7553 fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(union_field->name));7559 fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(union_field->name));
7560 }
7561 fprintf(out_h, "};\n\n");
7562 } else {
7563 fprintf(out_h, "union %s;\n", buf_ptr(&type_entry->name));
7554 }7564 }
7555 fprintf(out_h, "};\n\n");
7556 break;7565 break;
7557 case TypeTableEntryIdOpaque:7566 case TypeTableEntryIdOpaque:
7558 fprintf(out_h, "struct %s;\n\n", buf_ptr(&type_entry->name));7567 fprintf(out_h, "struct %s;\n\n", buf_ptr(&type_entry->name));
test/gen_h.zig+47
...@@ -76,4 +76,51 @@ pub fn addCases(cases: *tests.GenHContext) void {...@@ -76,4 +76,51 @@ pub fn addCases(cases: *tests.GenHContext) void {
76 \\TEST_EXPORT void entry(struct Foo foo, uint8_t bar[]);76 \\TEST_EXPORT void entry(struct Foo foo, uint8_t bar[]);
77 \\77 \\
78 );78 );
79
80 cases.add("ptr to zig struct",
81 \\const S = struct {
82 \\ a: u8,
83 \\};
84 \\
85 \\export fn a(s: *S) u8 {
86 \\ return s.a;
87 \\}
88
89 ,
90 \\struct S;
91 \\TEST_EXPORT uint8_t a(struct S * s);
92 \\
93 );
94
95 cases.add("ptr to zig union",
96 \\const U = union(enum) {
97 \\ A: u8,
98 \\ B: u16,
99 \\};
100 \\
101 \\export fn a(s: *U) u8 {
102 \\ return s.A;
103 \\}
104
105 ,
106 \\union U;
107 \\TEST_EXPORT uint8_t a(union U * s);
108 \\
109 );
110
111 cases.add("ptr to zig enum",
112 \\const E = enum(u8) {
113 \\ A,
114 \\ B,
115 \\};
116 \\
117 \\export fn a(s: *E) u8 {
118 \\ return @enumToInt(s.*);
119 \\}
120
121 ,
122 \\enum E;
123 \\TEST_EXPORT uint8_t a(enum E * s);
124 \\
125 );
79}126}