translate-c: check record fields for opaque demotions

This commit is contained in:
TwoClocks
2021-12-31 13:01:14 -08:00
committed by Veikka Tuominen
parent ee651c3cd3
commit 36b4658752
2 changed files with 34 additions and 1 deletions

View File

@@ -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);

View File

@@ -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);