Skip to content

Commit fd3a41d

Browse files
Hejsilandrewrk
authored andcommittedJul 18, 2018
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
1 parent c393a39 commit fd3a41d

File tree

3 files changed

+95
-37
lines changed

3 files changed

+95
-37
lines changed
 

‎src/analyze.cpp‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1454,7 +1454,9 @@ static bool type_allowed_in_extern(CodeGen *g, TypeTableEntry *type_entry) {
14541454
case TypeTableEntryIdFn:
14551455
return type_entry->data.fn.fn_type_id.cc == CallingConventionC;
14561456
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;
14581460
case TypeTableEntryIdStruct:
14591461
return type_entry->data.structure.layout == ContainerLayoutExtern || type_entry->data.structure.layout == ContainerLayoutPacked;
14601462
case TypeTableEntryIdOptional:

‎src/codegen.cpp‎

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7508,51 +7508,60 @@ static void gen_h_file(CodeGen *g) {
75087508
case TypeTableEntryIdPromise:
75097509
zig_unreachable();
75107510
case TypeTableEntryIdEnum:
7511-
assert(type_entry->data.enumeration.layout == ContainerLayoutExtern);
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) {
7514-
TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i];
7515-
Buf *value_buf = buf_alloc();
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));
7518-
if (field_i != type_entry->data.enumeration.src_field_count - 1) {
7519-
fprintf(out_h, ",");
7511+
if (type_entry->data.enumeration.layout == ContainerLayoutExtern) {
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) {
7514+
TypeEnumField *enum_field = &type_entry->data.enumeration.fields[field_i];
7515+
Buf *value_buf = buf_alloc();
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));
7518+
if (field_i != type_entry->data.enumeration.src_field_count - 1) {
7519+
fprintf(out_h, ",");
7520+
}
7521+
fprintf(out_h, "\n");
75207522
}
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));
75227526
}
7523-
fprintf(out_h, "};\n\n");
75247527
break;
75257528
case TypeTableEntryIdStruct:
7526-
assert(type_entry->data.structure.layout == ContainerLayoutExtern);
7527-
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) {
7529-
TypeStructField *struct_field = &type_entry->data.structure.fields[field_i];
7530-
7531-
Buf *type_name_buf = buf_alloc();
7532-
get_c_type(g, gen_h, struct_field->type_entry, type_name_buf);
7533-
7534-
if (struct_field->type_entry->id == TypeTableEntryIdArray) {
7535-
fprintf(out_h, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf),
7536-
buf_ptr(struct_field->name),
7537-
struct_field->type_entry->data.array.len);
7538-
} else {
7539-
fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name));
7540-
}
7529+
if (type_entry->data.structure.layout == ContainerLayoutExtern) {
7530+
fprintf(out_h, "struct %s {\n", buf_ptr(&type_entry->name));
7531+
for (uint32_t field_i = 0; field_i < type_entry->data.structure.src_field_count; field_i += 1) {
7532+
TypeStructField *struct_field = &type_entry->data.structure.fields[field_i];
7533+
7534+
Buf *type_name_buf = buf_alloc();
7535+
get_c_type(g, gen_h, struct_field->type_entry, type_name_buf);
7536+
7537+
if (struct_field->type_entry->id == TypeTableEntryIdArray) {
7538+
fprintf(out_h, " %s %s[%" ZIG_PRI_u64 "];\n", buf_ptr(type_name_buf),
7539+
buf_ptr(struct_field->name),
7540+
struct_field->type_entry->data.array.len);
7541+
} else {
7542+
fprintf(out_h, " %s %s;\n", buf_ptr(type_name_buf), buf_ptr(struct_field->name));
7543+
}
75417544

7545+
}
7546+
fprintf(out_h, "};\n\n");
7547+
} else {
7548+
fprintf(out_h, "struct %s;\n", buf_ptr(&type_entry->name));
75427549
}
7543-
fprintf(out_h, "};\n\n");
75447550
break;
75457551
case TypeTableEntryIdUnion:
7546-
assert(type_entry->data.unionation.layout == ContainerLayoutExtern);
7547-
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) {
7549-
TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i];
7550-
7551-
Buf *type_name_buf = buf_alloc();
7552-
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));
7552+
if (type_entry->data.unionation.layout == ContainerLayoutExtern) {
7553+
fprintf(out_h, "union %s {\n", buf_ptr(&type_entry->name));
7554+
for (uint32_t field_i = 0; field_i < type_entry->data.unionation.src_field_count; field_i += 1) {
7555+
TypeUnionField *union_field = &type_entry->data.unionation.fields[field_i];
7556+
7557+
Buf *type_name_buf = buf_alloc();
7558+
get_c_type(g, gen_h, union_field->type_entry, type_name_buf);
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));
75547564
}
7555-
fprintf(out_h, "};\n\n");
75567565
break;
75577566
case TypeTableEntryIdOpaque:
75587567
fprintf(out_h, "struct %s;\n\n", buf_ptr(&type_entry->name));

‎test/gen_h.zig‎

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,51 @@ pub fn addCases(cases: *tests.GenHContext) void {
7676
\\TEST_EXPORT void entry(struct Foo foo, uint8_t bar[]);
7777
\\
7878
);
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+
);
79126
}

0 commit comments

Comments
 (0)