Commit 36b4658752
Changed files (2)
test
src/translate_c.zig
@@ -4831,7 +4831,16 @@ fn qualTypeWasDemotedToOpaque(c: *Context, qt: clang.QualType) bool {
const record_decl = record_ty.getDecl();
const canonical = @ptrToInt(record_decl.getCanonicalDecl());
- return c.opaque_demotes.contains(canonical);
+ if (c.opaque_demotes.contains(canonical)) return true;
+
+ // check all childern for opaque types.
+ var it = record_decl.field_begin();
+ const end_it = record_decl.field_end();
+ while (it.neq(end_it)) : (it = it.next()) {
+ const field_decl = it.deref();
+ if (qualTypeWasDemotedToOpaque(c, field_decl.getType())) return true;
+ }
+ return false;
},
.Enum => {
const enum_ty = @ptrCast(*const clang.EnumType, ty);
test/translate_c.zig
@@ -3607,6 +3607,30 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub extern fn deref(arg_s: ?*struct_my_struct) void;
});
+ cases.add("Demote function that dereference types that contain opaque type",
+ \\struct inner {
+ \\ _Atomic int a;
+ \\};
+ \\struct outer {
+ \\ int thing;
+ \\ struct inner sub_struct;
+ \\};
+ \\void deref(struct outer *s) {
+ \\ *s;
+ \\}
+ , &[_][]const u8{
+ \\pub const struct_inner = opaque {};
+ ,
+ \\pub const struct_outer = extern struct {
+ \\ thing: c_int,
+ \\ sub_struct: struct_inner,
+ \\};
+ ,
+ \\warning: unable to translate function, demoted to extern
+ ,
+ \\pub extern fn deref(arg_s: ?*struct_outer) void;
+ });
+
cases.add("Function prototype declared within function",
\\int foo(void) {
\\ extern int bar(int, int);