mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 06:40:25 +00:00
Revert "reserve correct space for bitfields"
This reverts commit 22cb693889
.
This commit is contained in:
parent
22cb693889
commit
ee651c3cd3
@ -476,12 +476,6 @@ pub const FieldDecl = opaque {
|
||||
pub const isBitField = ZigClangFieldDecl_isBitField;
|
||||
extern fn ZigClangFieldDecl_isBitField(*const FieldDecl) bool;
|
||||
|
||||
pub const getBitWidthValue = ZigClangFieldDecl_getBitWidthValue;
|
||||
extern fn ZigClangFieldDecl_getBitWidthValue(*const FieldDecl, *const ASTContext) c_uint;
|
||||
|
||||
pub const isZeroLengthBitField = ZigClangFieldDecl_isZeroLengthBitField;
|
||||
extern fn ZigClangFieldDecl_isZeroLengthBitField(*const FieldDecl, *const ASTContext) bool;
|
||||
|
||||
pub const getType = ZigClangFieldDecl_getType;
|
||||
extern fn ZigClangFieldDecl_getType(*const FieldDecl) QualType;
|
||||
|
||||
|
@ -1085,15 +1085,17 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD
|
||||
const layout = record_def.getASTRecordLayout(c.clang_context);
|
||||
const record_alignment = layout.getAlignment();
|
||||
|
||||
var record_bitfield_count: u32 = 0;
|
||||
var bits_unused: i32 = 0;
|
||||
var bits_type: clang.BuiltinTypeKind = clang.BuiltinTypeKind.Void;
|
||||
|
||||
while (it.neq(end_it)) : (it = it.next()) {
|
||||
const field_decl = it.deref();
|
||||
const field_loc = field_decl.getLocation();
|
||||
const field_qt = field_decl.getType();
|
||||
|
||||
if (field_decl.isBitField()) {
|
||||
try c.opaque_demotes.put(c.gpa, @ptrToInt(record_decl.getCanonicalDecl()), {});
|
||||
try warn(c, scope, field_loc, "{s} demoted to opaque type - has bitfield", .{container_kind_name});
|
||||
break :blk Tag.opaque_literal.init();
|
||||
}
|
||||
|
||||
var is_anon = false;
|
||||
var field_name = try c.str(@ptrCast(*const clang.NamedDecl, field_decl).getName_bytes_begin());
|
||||
if (field_decl.isAnonymousStructOrUnion() or field_name.len == 0) {
|
||||
@ -1123,53 +1125,6 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD
|
||||
else => |e| return e,
|
||||
};
|
||||
|
||||
if (field_decl.isBitField()) {
|
||||
var this_field_width = @intCast(i32, field_decl.getBitWidthValue(c.clang_context));
|
||||
|
||||
// are we starting new bitfield?
|
||||
if (bits_unused <= 0) {
|
||||
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 } });
|
||||
|
||||
bits_type = @ptrCast(*const clang.BuiltinType, field_qt.getTypePtr()).getKind();
|
||||
|
||||
var field_width = field_type.castTag(.type).?.*.data; // we just set it 10 lines back. this should not fail.
|
||||
|
||||
if (size_map.get(field_width)) |sz| {
|
||||
bits_unused = @intCast(i32, sz) - this_field_width;
|
||||
field_name = try std.fmt.allocPrint(c.arena, "bitfield{d}", .{record_bitfield_count});
|
||||
record_bitfield_count += 1;
|
||||
} else {
|
||||
try warn(c, scope, field_loc, "{s} demoted to opaque type - bitfield type not unsigned or unknown. type:{s} ", .{ container_kind_name, field_width });
|
||||
break :blk Tag.opaque_literal.init();
|
||||
}
|
||||
} else {
|
||||
var this_type = @ptrCast(*const clang.BuiltinType, field_qt.getTypePtr()).getKind();
|
||||
if (field_decl.isZeroLengthBitField(c.clang_context)) {
|
||||
try warn(c, scope, field_loc, "{s} demoted to opaque type - bitfield with zero size not supported", .{container_kind_name});
|
||||
break :blk Tag.opaque_literal.init();
|
||||
} else if (bits_type != this_type) {
|
||||
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) });
|
||||
break :blk Tag.opaque_literal.init();
|
||||
} else {
|
||||
// next
|
||||
bits_unused -= this_field_width;
|
||||
if (bits_unused < 0) {
|
||||
try warn(c, scope, field_loc, "{s} demoted to opaque type - bitfield overrun type size not supported", .{container_kind_name});
|
||||
break :blk Tag.opaque_literal.init();
|
||||
}
|
||||
}
|
||||
continue; // free the field_type? tag is alloc'd
|
||||
}
|
||||
} else {
|
||||
if (bits_unused >= 8) {
|
||||
// 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,
|
||||
// the layout is to compiler specific.
|
||||
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 });
|
||||
break :blk Tag.opaque_literal.init();
|
||||
}
|
||||
bits_unused = 0;
|
||||
}
|
||||
|
||||
const alignment = if (has_flexible_array and field_decl.getFieldIndex() == 0)
|
||||
@intCast(c_uint, record_alignment)
|
||||
else
|
||||
@ -1185,10 +1140,6 @@ fn transRecordDecl(c: *Context, scope: *Scope, record_decl: *const clang.RecordD
|
||||
.alignment = alignment,
|
||||
});
|
||||
}
|
||||
if (bits_unused >= 8) { // one last check if the last field was a bitfield
|
||||
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 });
|
||||
break :blk Tag.opaque_literal.init();
|
||||
}
|
||||
|
||||
const record_payload = try c.arena.create(ast.Payload.Record);
|
||||
record_payload.* = .{
|
||||
@ -2625,9 +2576,7 @@ fn transInitListExprRecord(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (init_i >= init_count) {
|
||||
return fail(c, error.UnsupportedTranslation, loc, "init list longer fields in record. Record has bitfield?", .{});
|
||||
}
|
||||
assert(init_i < init_count);
|
||||
const elem_expr = expr.getInit(init_i);
|
||||
init_i += 1;
|
||||
|
||||
|
@ -3335,18 +3335,6 @@ bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *self) {
|
||||
return casted->isBitField();
|
||||
}
|
||||
|
||||
unsigned ZigClangFieldDecl_getBitWidthValue( const struct ZigClangFieldDecl *self, const ZigClangASTContext *ctx) {
|
||||
auto casted = reinterpret_cast<const clang::FieldDecl *>(self);
|
||||
auto casted_ctx = const_cast<clang::ASTContext *>(reinterpret_cast<const clang::ASTContext *>(ctx));
|
||||
return casted->getBitWidthValue(*casted_ctx);
|
||||
}
|
||||
|
||||
bool ZigClangFieldDecl_isZeroLengthBitField( ZigClangFieldDecl *self, const ZigClangASTContext *ctx) {
|
||||
auto casted = reinterpret_cast<const clang::FieldDecl *>(self);
|
||||
auto casted_ctx = const_cast<clang::ASTContext *>(reinterpret_cast<const clang::ASTContext *>(ctx));
|
||||
return casted->isZeroLengthBitField(*casted_ctx);
|
||||
}
|
||||
|
||||
bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *field_decl) {
|
||||
return reinterpret_cast<const clang::FieldDecl*>(field_decl)->isAnonymousStructOrUnion();
|
||||
}
|
||||
|
@ -1407,8 +1407,6 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSour
|
||||
ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSourceRange_getEnd(const struct ZigClangMacroDefinitionRecord *);
|
||||
|
||||
ZIG_EXTERN_C bool ZigClangFieldDecl_isBitField(const struct ZigClangFieldDecl *);
|
||||
ZIG_EXTERN_C unsigned ZigClangFieldDecl_getBitWidthValue( const struct ZigClangFieldDecl *, const ZigClangASTContext *);
|
||||
ZIG_EXTERN_C bool ZigClangFieldDecl_isZeroLengthBitField( ZigClangFieldDecl *, const ZigClangASTContext *);
|
||||
ZIG_EXTERN_C bool ZigClangFieldDecl_isAnonymousStructOrUnion(const ZigClangFieldDecl *);
|
||||
ZIG_EXTERN_C struct ZigClangQualType ZigClangFieldDecl_getType(const struct ZigClangFieldDecl *);
|
||||
ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFieldDecl_getLocation(const struct ZigClangFieldDecl *);
|
||||
|
@ -915,6 +915,21 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\};
|
||||
});
|
||||
|
||||
cases.add("pointer to struct demoted to opaque due to bit fields",
|
||||
\\struct Foo {
|
||||
\\ unsigned int: 1;
|
||||
\\};
|
||||
\\struct Bar {
|
||||
\\ struct Foo *foo;
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\pub const struct_Foo = opaque {};
|
||||
,
|
||||
\\pub const struct_Bar = extern struct {
|
||||
\\ foo: ?*struct_Foo,
|
||||
\\};
|
||||
});
|
||||
|
||||
cases.add("macro with left shift",
|
||||
\\#define REDISMODULE_READ (1<<0)
|
||||
, &[_][]const u8{
|
||||
@ -3562,33 +3577,34 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("function that dereferences bitfield works",
|
||||
cases.add("Demote function that initializes opaque struct",
|
||||
\\struct my_struct {
|
||||
\\ unsigned a: 15;
|
||||
\\ unsigned: 2;
|
||||
\\ unsigned b: 15;
|
||||
\\};
|
||||
\\void initialize(void) {
|
||||
\\ struct my_struct S = {.a = 1, .b = 2};
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\warning: cannot initialize opaque type
|
||||
,
|
||||
\\warning: unable to translate function, demoted to extern
|
||||
\\pub extern fn initialize() void;
|
||||
});
|
||||
|
||||
cases.add("Demote function that dereferences opaque type",
|
||||
\\struct my_struct {
|
||||
\\ unsigned a: 1;
|
||||
\\ unsigned b: 28;
|
||||
\\};
|
||||
\\void deref(struct my_struct *s) {
|
||||
\\ *s;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
\\pub const struct_my_struct = extern struct {
|
||||
\\ bitfield0: c_uint,
|
||||
\\warning: cannot dereference opaque type
|
||||
,
|
||||
\\pub export fn deref(arg_s: ?*struct_my_struct) void {
|
||||
\\ var s = arg_s;
|
||||
\\ _ = s.*;
|
||||
\\}
|
||||
});
|
||||
|
||||
cases.add("bitfield don't cover requedted space",
|
||||
\\struct inner {
|
||||
\\ unsigned a: 1;
|
||||
\\ char after;
|
||||
\\};
|
||||
, &[_][]const u8{
|
||||
\\less bits used than field size.
|
||||
,
|
||||
\\pub const struct_inner = opaque {};
|
||||
\\warning: unable to translate function, demoted to extern
|
||||
\\pub extern fn deref(arg_s: ?*struct_my_struct) void;
|
||||
});
|
||||
|
||||
cases.add("Function prototype declared within function",
|
||||
|
Loading…
Reference in New Issue
Block a user