authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-05-29 12:04:50+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-05-29 12:04:50+03:00
logee651c3cd358f40f60db0bbcd82ffde99aed9b88
tree5d5830d5b3ce6c13041aacb7e073763551cb4852
parent22cb6938891c73d64b749a2516c8eaf79aa25b03

Revert "reserve correct space for bitfields"

This reverts commit 22cb6938891c73d64b749a2516c8eaf79aa25b03.

5 files changed, 39 insertions(+), 94 deletions(-)

src/clang.zig-6
......@@ -476,12 +476,6 @@ pub const FieldDecl = opaque {
476476 pub const isBitField = ZigClangFieldDecl_isBitField;
477477 extern fn ZigClangFieldDecl_isBitField(*const FieldDecl) bool;
478478
479 pub const getBitWidthValue = ZigClangFieldDecl_getBitWidthValue;
480 extern fn ZigClangFieldDecl_getBitWidthValue(*const FieldDecl, *const ASTContext) c_uint;
481
482 pub const isZeroLengthBitField = ZigClangFieldDecl_isZeroLengthBitField;
483 extern fn ZigClangFieldDecl_isZeroLengthBitField(*const FieldDecl, *const ASTContext) bool;
484
485479 pub const getType = ZigClangFieldDecl_getType;
486480 extern fn ZigClangFieldDecl_getType(*const FieldDecl) QualType;
487481
src/translate_c.zig+7-58
......@@ -1085,15 +1085,17 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD
10851085 const layout = record_def.getASTRecordLayout(c.clang_context);
10861086 const record_alignment = layout.getAlignment();
10871087
1088 var record_bitfield_count: u32 = 0;
1089 var bits_unused: i32 = 0;
1090 var bits_type: clang.BuiltinTypeKind = clang.BuiltinTypeKind.Void;
1091
10921088 while (it.neq(end_it)) : (it = it.next()) {
10931089 const field_decl = it.deref();
10941090 const field_loc = field_decl.getLocation();
10951091 const field_qt = field_decl.getType();
10961092
1093 if (field_decl.isBitField()) {
1094 try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
1095 try warn(c, scope, field_loc, "{s} demoted to opaque type - has bitfield", .{container_kind_name});
1096 break :blk Tag.opaque_literal.init();
1097 }
1098
10971099 var is_anon = false;
10981100 var field_name = try c.str(@ptrCast(*const clang.NamedDecl, field_decl).getName_bytes_begin());
10991101 if (field_decl.isAnonymousStructOrUnion() or field_name.len == 0) {
......@@ -1123,53 +1125,6 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD
11231125 else => |e| return e,
11241126 };
11251127
1126 if (field_decl.isBitField()) {
1127 var this_field_width = @intCast(i32, field_decl.getBitWidthValue(c.clang_context));
1128
1129 // are we starting new bitfield?
1130 if (bits_unused <= 0) {
1131 const size_map = std.ComptimeStringMap(u16, .{ .{ "u8", 8 }, .{ "c_ushort", 16 }, .{ "u16", 16 }, .{ "u32", 32 }, .{ "c_uint", 32 }, .{ "c_ulong", 32 }, .{ "c_ulonglong", 64 }, .{ "u64", 64 } });
1132
1133 bits_type = @ptrCast(*const clang.BuiltinType, field_qt.getTypePtr()).getKind();
1134
1135 var field_width = field_type.castTag(.type).?.*.data; // we just set it 10 lines back. this should not fail.
1136
1137 if (size_map.get(field_width)) |sz| {
1138 bits_unused = @intCast(i32, sz) - this_field_width;
1139 field_name = try std.fmt.allocPrint(c.arena, "bitfield{d}", .{record_bitfield_count});
1140 record_bitfield_count += 1;
1141 } else {
1142 try warn(c, scope, field_loc, "{s} demoted to opaque type - bitfield type not unsigned or unknown. type:{s} ", .{ container_kind_name, field_width });
1143 break :blk Tag.opaque_literal.init();
1144 }
1145 } else {
1146 var this_type = @ptrCast(*const clang.BuiltinType, field_qt.getTypePtr()).getKind();
1147 if (field_decl.isZeroLengthBitField(c.clang_context)) {
1148 try warn(c, scope, field_loc, "{s} demoted to opaque type - bitfield with zero size not supported", .{container_kind_name});
1149 break :blk Tag.opaque_literal.init();
1150 } else if (bits_type != this_type) {
1151 try warn(c, scope, field_loc, "{s} demoted to opaque type - bitfield type changed in the middle of bitfield was;{s} is:{s}", .{ container_kind_name, @tagName(bits_type), @tagName(this_type) });
1152 break :blk Tag.opaque_literal.init();
1153 } else {
1154 // next
1155 bits_unused -= this_field_width;
1156 if (bits_unused < 0) {
1157 try warn(c, scope, field_loc, "{s} demoted to opaque type - bitfield overrun type size not supported", .{container_kind_name});
1158 break :blk Tag.opaque_literal.init();
1159 }
1160 }
1161 continue; // free the field_type? tag is alloc'd
1162 }
1163 } else {
1164 if (bits_unused >= 8) {
1165 // if they didn't add a "reserved:n" at the end, and the # of bits used is more than 1 byte of their requested size,
1166 // the layout is to compiler specific.
1167 try warn(c, scope, field_loc, "{s} demoted to opaque type - less bits used than field size. unused bit count:{d}", .{ container_kind_name, bits_unused });
1168 break :blk Tag.opaque_literal.init();
1169 }
1170 bits_unused = 0;
1171 }
1172
11731128 const alignment = if (has_flexible_array and field_decl.getFieldIndex() == 0)
11741129 @intCast(c_uint, record_alignment)
11751130 else
......@@ -1185,10 +1140,6 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD
11851140 .alignment = alignment,
11861141 });
11871142 }
1188 if (bits_unused >= 8) { // one last check if the last field was a bitfield
1189 try warn(c, scope, record_loc, "{s} demoted to opaque type - less bits used than field size. unused bit count:{d}", .{ container_kind_name, bits_unused });
1190 break :blk Tag.opaque_literal.init();
1191 }
11921143
11931144 const record_payload = try c.arena.create(ast.Payload.Record);
11941145 record_payload.* = .{
......@@ -2625,9 +2576,7 @@ fn transInitListExprRecord(
26252576 continue;
26262577 }
26272578
2628 if (init_i >= init_count) {
2629 return fail(c, error.UnsupportedTranslation, loc, "init list longer fields in record. Record has bitfield?", .{});
2630 }
2579 assert(init_i < init_count);
26312580 const elem_expr = expr.getInit(init_i);
26322581 init_i += 1;
26332582
src/zig_clang.cpp-12
......@@ -3335,18 +3335,6 @@ bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *self) {
33353335 return casted->isBitField();
33363336}
33373337
3338unsigned ZigClangFieldDecl_getBitWidthValue( const struct ZigClangFieldDecl *self, const ZigClangASTContext *ctx) {
3339 auto casted = reinterpret_cast<const clang::FieldDecl *>(self);
3340 auto casted_ctx = const_cast<clang::ASTContext *>(reinterpret_cast<const clang::ASTContext *>(ctx));
3341 return casted->getBitWidthValue(*casted_ctx);
3342}
3343
3344bool ZigClangFieldDecl_isZeroLengthBitField( ZigClangFieldDecl *self, const ZigClangASTContext *ctx) {
3345 auto casted = reinterpret_cast<const clang::FieldDecl *>(self);
3346 auto casted_ctx = const_cast<clang::ASTContext *>(reinterpret_cast<const clang::ASTContext *>(ctx));
3347 return casted->isZeroLengthBitField(*casted_ctx);
3348}
3349
33503338bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *field_decl) {
33513339 return reinterpret_cast<const clang::FieldDecl*>(field_decl)->isAnonymousStructOrUnion();
33523340}
src/zig_clang.h-2
......@@ -1407,8 +1407,6 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSour
14071407ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSourceRange_getEnd(const struct ZigClangMacroDefinitionRecord *);
14081408
14091409ZIG_EXTERN_C bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *);
1410ZIG_EXTERN_C unsigned ZigClangFieldDecl_getBitWidthValue( const struct ZigClangFieldDecl *, const ZigClangASTContext *);
1411ZIG_EXTERN_C bool ZigClangFieldDecl_isZeroLengthBitField( ZigClangFieldDecl *, const ZigClangASTContext *);
14121410ZIG_EXTERN_C bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *);
14131411ZIG_EXTERN_C struct ZigClangQualType ZigClangFieldDecl_getType(const struct ZigClangFieldDecl *);
14141412ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFieldDecl_getLocation(const struct ZigClangFieldDecl *);
test/translate_c.zig+32-16
......@@ -915,6 +915,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
915915 \\};
916916 });
917917
918 cases.add("pointer to struct demoted to opaque due to bit fields",
919 \\struct Foo {
920 \\ unsigned int: 1;
921 \\};
922 \\struct Bar {
923 \\ struct Foo *foo;
924 \\};
925 , &[_][]const u8{
926 \\pub const struct_Foo = opaque {};
927 ,
928 \\pub const struct_Bar = extern struct {
929 \\ foo: ?*struct_Foo,
930 \\};
931 });
932
918933 cases.add("macro with left shift",
919934 \\#define REDISMODULE_READ (1<<0)
920935 , &[_][]const u8{
......@@ -3562,33 +3577,34 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
35623577 \\}
35633578 });
35643579
3565 cases.add("function that dereferences bitfield works",
3580 cases.add("Demote function that initializes opaque struct",
35663581 \\struct my_struct {
3567 \\ unsigned a: 1;
3568 \\ unsigned b: 28;
3582 \\ unsigned a: 15;
3583 \\ unsigned: 2;
3584 \\ unsigned b: 15;
35693585 \\};
3570 \\void deref(struct my_struct *s) {
3571 \\ *s;
3586 \\void initialize(void) {
3587 \\ struct my_struct S = {.a = 1, .b = 2};
35723588 \\}
35733589 , &[_][]const u8{
3574 \\pub const struct_my_struct = extern struct {
3575 \\ bitfield0: c_uint,
3590 \\warning: cannot initialize opaque type
35763591 ,
3577 \\pub export fn deref(arg_s: ?*struct_my_struct) void {
3578 \\ var s = arg_s;
3579 \\ _ = s.*;
3580 \\}
3592 \\warning: unable to translate function, demoted to extern
3593 \\pub extern fn initialize() void;
35813594 });
35823595
3583 cases.add("bitfield don't cover requedted space",
3584 \\struct inner {
3596 cases.add("Demote function that dereferences opaque type",
3597 \\struct my_struct {
35853598 \\ unsigned a: 1;
3586 \\ char after;
35873599 \\};
3600 \\void deref(struct my_struct *s) {
3601 \\ *s;
3602 \\}
35883603 , &[_][]const u8{
3589 \\less bits used than field size.
3604 \\warning: cannot dereference opaque type
35903605 ,
3591 \\pub const struct_inner = opaque {};
3606 \\warning: unable to translate function, demoted to extern
3607 \\pub extern fn deref(arg_s: ?*struct_my_struct) void;
35923608 });
35933609
35943610 cases.add("Function prototype declared within function",