| author | |
| committer | |
| log | ee651c3cd358f40f60db0bbcd82ffde99aed9b88 |
| tree | 5d5830d5b3ce6c13041aacb7e073763551cb4852 |
| parent | 22cb6938891c73d64b749a2516c8eaf79aa25b03 |
This reverts commit 22cb6938891c73d64b749a2516c8eaf79aa25b03.5 files changed, 39 insertions(+), 94 deletions(-)
src/clang.zig-6| ... | @@ -476,12 +476,6 @@ pub const FieldDecl = opaque { | ... | @@ -476,12 +476,6 @@ pub const FieldDecl = opaque { |
| 476 | pub const isBitField = ZigClangFieldDecl_isBitField; | 476 | pub const isBitField = ZigClangFieldDecl_isBitField; |
| 477 | extern fn ZigClangFieldDecl_isBitField(*const FieldDecl) bool; | 477 | extern fn ZigClangFieldDecl_isBitField(*const FieldDecl) bool; |
| 478 | 478 | ||
| 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 | |||
| 485 | pub const getType = ZigClangFieldDecl_getType; | 479 | pub const getType = ZigClangFieldDecl_getType; |
| 486 | extern fn ZigClangFieldDecl_getType(*const FieldDecl) QualType; | 480 | extern fn ZigClangFieldDecl_getType(*const FieldDecl) QualType; |
| 487 | 481 |
src/translate_c.zig+7-58| ... | @@ -1085,15 +1085,17 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD | ... | @@ -1085,15 +1085,17 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD |
| 1085 | const layout = record_def.getASTRecordLayout(c.clang_context); | 1085 | const layout = record_def.getASTRecordLayout(c.clang_context); |
| 1086 | const record_alignment = layout.getAlignment(); | 1086 | const record_alignment = layout.getAlignment(); |
| 1087 | 1087 | ||
| 1088 | var record_bitfield_count: u32 = 0; | ||
| 1089 | var bits_unused: i32 = 0; | ||
| 1090 | var bits_type: clang.BuiltinTypeKind = clang.BuiltinTypeKind.Void; | ||
| 1091 | |||
| 1092 | while (it.neq(end_it)) : (it = it.next()) { | 1088 | while (it.neq(end_it)) : (it = it.next()) { |
| 1093 | const field_decl = it.deref(); | 1089 | const field_decl = it.deref(); |
| 1094 | const field_loc = field_decl.getLocation(); | 1090 | const field_loc = field_decl.getLocation(); |
| 1095 | const field_qt = field_decl.getType(); | 1091 | const field_qt = field_decl.getType(); |
| 1096 | 1092 | ||
| 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 | |||
| 1097 | var is_anon = false; | 1099 | var is_anon = false; |
| 1098 | var field_name = try c.str(@ptrCast(*const clang.NamedDecl, field_decl).getName_bytes_begin()); | 1100 | var field_name = try c.str(@ptrCast(*const clang.NamedDecl, field_decl).getName_bytes_begin()); |
| 1099 | if (field_decl.isAnonymousStructOrUnion() or field_name.len == 0) { | 1101 | if (field_decl.isAnonymousStructOrUnion() or field_name.len == 0) { |
| ... | @@ -1123,53 +1125,6 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD | ... | @@ -1123,53 +1125,6 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD |
| 1123 | else => |e| return e, | 1125 | else => |e| return e, |
| 1124 | }; | 1126 | }; |
| 1125 | 1127 | ||
| 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 | |||
| 1173 | const alignment = if (has_flexible_array and field_decl.getFieldIndex() == 0) | 1128 | const alignment = if (has_flexible_array and field_decl.getFieldIndex() == 0) |
| 1174 | @intCast(c_uint, record_alignment) | 1129 | @intCast(c_uint, record_alignment) |
| 1175 | else | 1130 | else |
| ... | @@ -1185,10 +1140,6 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD | ... | @@ -1185,10 +1140,6 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD |
| 1185 | .alignment = alignment, | 1140 | .alignment = alignment, |
| 1186 | }); | 1141 | }); |
| 1187 | } | 1142 | } |
| 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 | } | ||
| 1192 | 1143 | ||
| 1193 | const record_payload = try c.arena.create(ast.Payload.Record); | 1144 | const record_payload = try c.arena.create(ast.Payload.Record); |
| 1194 | record_payload.* = .{ | 1145 | record_payload.* = .{ |
| ... | @@ -2625,9 +2576,7 @@ fn transInitListExprRecord( | ... | @@ -2625,9 +2576,7 @@ fn transInitListExprRecord( |
| 2625 | continue; | 2576 | continue; |
| 2626 | } | 2577 | } |
| 2627 | 2578 | ||
| 2628 | if (init_i >= init_count) { | 2579 | assert(init_i < init_count); |
| 2629 | return fail(c, error.UnsupportedTranslation, loc, "init list longer fields in record. Record has bitfield?", .{}); | ||
| 2630 | } | ||
| 2631 | const elem_expr = expr.getInit(init_i); | 2580 | const elem_expr = expr.getInit(init_i); |
| 2632 | init_i += 1; | 2581 | init_i += 1; |
| 2633 | 2582 |
src/zig_clang.cpp-12| ... | @@ -3335,18 +3335,6 @@ bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *self) { | ... | @@ -3335,18 +3335,6 @@ bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *self) { |
| 3335 | return casted->isBitField(); | 3335 | return casted->isBitField(); |
| 3336 | } | 3336 | } |
| 3337 | 3337 | ||
| 3338 | unsigned 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 | |||
| 3344 | bool 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 | |||
| 3350 | bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *field_decl) { | 3338 | bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *field_decl) { |
| 3351 | return reinterpret_cast<const clang::FieldDecl*>(field_decl)->isAnonymousStructOrUnion(); | 3339 | return reinterpret_cast<const clang::FieldDecl*>(field_decl)->isAnonymousStructOrUnion(); |
| 3352 | } | 3340 | } |
src/zig_clang.h-2| ... | @@ -1407,8 +1407,6 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSour | ... | @@ -1407,8 +1407,6 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSour |
| 1407 | ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSourceRange_getEnd(const struct ZigClangMacroDefinitionRecord *); | 1407 | ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSourceRange_getEnd(const struct ZigClangMacroDefinitionRecord *); |
| 1408 | 1408 | ||
| 1409 | ZIG_EXTERN_C bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *); | 1409 | ZIG_EXTERN_C bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *); |
| 1410 | ZIG_EXTERN_C unsigned ZigClangFieldDecl_getBitWidthValue( const struct ZigClangFieldDecl *, const ZigClangASTContext *); | ||
| 1411 | ZIG_EXTERN_C bool ZigClangFieldDecl_isZeroLengthBitField( ZigClangFieldDecl *, const ZigClangASTContext *); | ||
| 1412 | ZIG_EXTERN_C bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *); | 1410 | ZIG_EXTERN_C bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *); |
| 1413 | ZIG_EXTERN_C struct ZigClangQualType ZigClangFieldDecl_getType(const struct ZigClangFieldDecl *); | 1411 | ZIG_EXTERN_C struct ZigClangQualType ZigClangFieldDecl_getType(const struct ZigClangFieldDecl *); |
| 1414 | ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFieldDecl_getLocation(const struct ZigClangFieldDecl *); | 1412 | ZIG_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 { | ... | @@ -915,6 +915,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 915 | \\}; | 915 | \\}; |
| 916 | }); | 916 | }); |
| 917 | 917 | ||
| 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 | |||
| 918 | cases.add("macro with left shift", | 933 | cases.add("macro with left shift", |
| 919 | \\#define REDISMODULE_READ (1<<0) | 934 | \\#define REDISMODULE_READ (1<<0) |
| 920 | , &[_][]const u8{ | 935 | , &[_][]const u8{ |
| ... | @@ -3562,33 +3577,34 @@ pub fn addCases(cases: *tests.TranslateCContext) void { | ... | @@ -3562,33 +3577,34 @@ pub fn addCases(cases: *tests.TranslateCContext) void { |
| 3562 | \\} | 3577 | \\} |
| 3563 | }); | 3578 | }); |
| 3564 | 3579 | ||
| 3565 | cases.add("function that dereferences bitfield works", | 3580 | cases.add("Demote function that initializes opaque struct", |
| 3566 | \\struct my_struct { | 3581 | \\struct my_struct { |
| 3567 | \\ unsigned a: 1; | 3582 | \\ unsigned a: 15; |
| 3568 | \\ unsigned b: 28; | 3583 | \\ unsigned: 2; |
| 3584 | \\ unsigned b: 15; | ||
| 3569 | \\}; | 3585 | \\}; |
| 3570 | \\void deref(struct my_struct *s) { | 3586 | \\void initialize(void) { |
| 3571 | \\ *s; | 3587 | \\ struct my_struct S = {.a = 1, .b = 2}; |
| 3572 | \\} | 3588 | \\} |
| 3573 | , &[_][]const u8{ | 3589 | , &[_][]const u8{ |
| 3574 | \\pub const struct_my_struct = extern struct { | 3590 | \\warning: cannot initialize opaque type |
| 3575 | \\ bitfield0: c_uint, | ||
| 3576 | , | 3591 | , |
| 3577 | \\pub export fn deref(arg_s: ?*struct_my_struct) void { | 3592 | \\warning: unable to translate function, demoted to extern |
| 3578 | \\ var s = arg_s; | 3593 | \\pub extern fn initialize() void; |
| 3579 | \\ _ = s.*; | ||
| 3580 | \\} | ||
| 3581 | }); | 3594 | }); |
| 3582 | 3595 | ||
| 3583 | cases.add("bitfield don't cover requedted space", | 3596 | cases.add("Demote function that dereferences opaque type", |
| 3584 | \\struct inner { | 3597 | \\struct my_struct { |
| 3585 | \\ unsigned a: 1; | 3598 | \\ unsigned a: 1; |
| 3586 | \\ char after; | ||
| 3587 | \\}; | 3599 | \\}; |
| 3600 | \\void deref(struct my_struct *s) { | ||
| 3601 | \\ *s; | ||
| 3602 | \\} | ||
| 3588 | , &[_][]const u8{ | 3603 | , &[_][]const u8{ |
| 3589 | \\less bits used than field size. | 3604 | \\warning: cannot dereference opaque type |
| 3590 | , | 3605 | , |
| 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; | ||
| 3592 | }); | 3608 | }); |
| 3593 | 3609 | ||
| 3594 | cases.add("Function prototype declared within function", | 3610 | cases.add("Function prototype declared within function", |