mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
translate-c: fix enums that require c_uint type
This commit is contained in:
parent
986a71234b
commit
b5c117d051
@ -1117,9 +1117,7 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E
|
|||||||
// default to the usual integer type used for all the enums.
|
// default to the usual integer type used for all the enums.
|
||||||
|
|
||||||
// default to c_int since msvc and gcc default to different types
|
// default to c_int since msvc and gcc default to different types
|
||||||
const init_arg_expr = if (int_type.ptr != null and
|
const init_arg_expr = if (int_type.ptr != null)
|
||||||
!isCBuiltinType(int_type, .UInt) and
|
|
||||||
!isCBuiltinType(int_type, .Int))
|
|
||||||
transQualType(c, scope, int_type, enum_loc) catch |err| switch (err) {
|
transQualType(c, scope, int_type, enum_loc) catch |err| switch (err) {
|
||||||
error.UnsupportedType => {
|
error.UnsupportedType => {
|
||||||
return failDecl(c, enum_loc, name, "unable to translate enum tag type", .{});
|
return failDecl(c, enum_loc, name, "unable to translate enum tag type", .{});
|
||||||
@ -2285,8 +2283,8 @@ fn transCCast(
|
|||||||
// 1. If src_type is an enum, determine the underlying signed int type
|
// 1. If src_type is an enum, determine the underlying signed int type
|
||||||
// 2. Extend or truncate without changing signed-ness.
|
// 2. Extend or truncate without changing signed-ness.
|
||||||
// 3. Bit-cast to correct signed-ness
|
// 3. Bit-cast to correct signed-ness
|
||||||
const src_type_is_signed = cIsSignedInteger(src_type) or cIsEnum(src_type);
|
|
||||||
const src_int_type = if (cIsInteger(src_type)) src_type else cIntTypeForEnum(src_type);
|
const src_int_type = if (cIsInteger(src_type)) src_type else cIntTypeForEnum(src_type);
|
||||||
|
const src_type_is_signed = cIsSignedInteger(src_int_type);
|
||||||
var src_int_expr = if (cIsInteger(src_type)) expr else try Tag.enum_to_int.create(c.arena, expr);
|
var src_int_expr = if (cIsInteger(src_type)) expr else try Tag.enum_to_int.create(c.arena, expr);
|
||||||
|
|
||||||
if (isBoolRes(src_int_expr)) {
|
if (isBoolRes(src_int_expr)) {
|
||||||
|
|||||||
@ -1540,4 +1540,14 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
|
|||||||
\\ return 0;
|
\\ return 0;
|
||||||
\\}
|
\\}
|
||||||
, "");
|
, "");
|
||||||
|
|
||||||
|
cases.add("enum with value that fits in c_uint but not c_int, issue #8003",
|
||||||
|
\\#include <stdlib.h>
|
||||||
|
\\enum my_enum {
|
||||||
|
\\ FORCE_UINT = 0xffffffff
|
||||||
|
\\};
|
||||||
|
\\int main(void) {
|
||||||
|
\\ if(FORCE_UINT != 0xffffffff) abort();
|
||||||
|
\\}
|
||||||
|
, "");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,8 @@ const std = @import("std");
|
|||||||
const CrossTarget = std.zig.CrossTarget;
|
const CrossTarget = std.zig.CrossTarget;
|
||||||
|
|
||||||
pub fn addCases(cases: *tests.TranslateCContext) void {
|
pub fn addCases(cases: *tests.TranslateCContext) void {
|
||||||
|
const default_enum_type = if (std.Target.current.abi == .msvc) "c_int" else "c_uint";
|
||||||
|
|
||||||
cases.add("field access is grouped if necessary",
|
cases.add("field access is grouped if necessary",
|
||||||
\\unsigned long foo(unsigned long x) {
|
\\unsigned long foo(unsigned long x) {
|
||||||
\\ return ((union{unsigned long _x}){x})._x;
|
\\ return ((union{unsigned long _x}){x})._x;
|
||||||
@ -28,17 +30,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\ int a, b;
|
\\ int a, b;
|
||||||
\\} Bar;
|
\\} Bar;
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
\\pub const Foo = extern enum(c_int) {
|
\\pub const Foo = extern enum(
|
||||||
\\ A,
|
++ default_enum_type ++
|
||||||
\\ B,
|
\\) {
|
||||||
\\ _,
|
\\ A,
|
||||||
\\};
|
\\ B,
|
||||||
\\pub const FooA = @enumToInt(Foo.A);
|
\\ _,
|
||||||
\\pub const FooB = @enumToInt(Foo.B);
|
\\};
|
||||||
\\pub const Bar = extern struct {
|
\\pub const FooA = @enumToInt(Foo.A);
|
||||||
\\ a: c_int,
|
\\pub const FooB = @enumToInt(Foo.B);
|
||||||
\\ b: c_int,
|
\\pub const Bar = extern struct {
|
||||||
\\};
|
\\ a: c_int,
|
||||||
|
\\ b: c_int,
|
||||||
|
\\};
|
||||||
});
|
});
|
||||||
|
|
||||||
cases.add("if as while stmt has semicolon",
|
cases.add("if as while stmt has semicolon",
|
||||||
@ -118,29 +122,33 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
\\pub export fn foo() void {
|
\\pub export fn foo() void {
|
||||||
\\ const enum_Foo = extern enum(c_int) {
|
\\ const enum_Foo = extern enum(
|
||||||
\\ A,
|
++ default_enum_type ++
|
||||||
\\ B,
|
\\) {
|
||||||
\\ C,
|
\\ A,
|
||||||
\\ _,
|
\\ B,
|
||||||
\\ };
|
\\ C,
|
||||||
\\ const A = @enumToInt(enum_Foo.A);
|
\\ _,
|
||||||
\\ const B = @enumToInt(enum_Foo.B);
|
\\ };
|
||||||
\\ const C = @enumToInt(enum_Foo.C);
|
\\ const A = @enumToInt(enum_Foo.A);
|
||||||
\\ var a: enum_Foo = @import("std").meta.cast(enum_Foo, B);
|
\\ const B = @enumToInt(enum_Foo.B);
|
||||||
\\ {
|
\\ const C = @enumToInt(enum_Foo.C);
|
||||||
\\ const enum_Foo = extern enum(c_int) {
|
\\ var a: enum_Foo = @import("std").meta.cast(enum_Foo, B);
|
||||||
\\ A,
|
\\ {
|
||||||
\\ B,
|
\\ const enum_Foo = extern enum(
|
||||||
\\ C,
|
++ default_enum_type ++
|
||||||
\\ _,
|
\\) {
|
||||||
\\ };
|
\\ A,
|
||||||
\\ const A_2 = @enumToInt(enum_Foo.A);
|
\\ B,
|
||||||
\\ const B_3 = @enumToInt(enum_Foo.B);
|
\\ C,
|
||||||
\\ const C_4 = @enumToInt(enum_Foo.C);
|
\\ _,
|
||||||
\\ var a_5: enum_Foo = @import("std").meta.cast(enum_Foo, B_3);
|
\\ };
|
||||||
\\ }
|
\\ const A_2 = @enumToInt(enum_Foo.A);
|
||||||
\\}
|
\\ const B_3 = @enumToInt(enum_Foo.B);
|
||||||
|
\\ const C_4 = @enumToInt(enum_Foo.C);
|
||||||
|
\\ var a_5: enum_Foo = @import("std").meta.cast(enum_Foo, B_3);
|
||||||
|
\\ }
|
||||||
|
\\}
|
||||||
});
|
});
|
||||||
|
|
||||||
cases.add("scoped record",
|
cases.add("scoped record",
|
||||||
@ -1702,47 +1710,55 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\ p,
|
\\ p,
|
||||||
\\};
|
\\};
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
\\pub const d = extern enum(c_int) {
|
\\pub const d = extern enum(
|
||||||
\\ a,
|
++ default_enum_type ++
|
||||||
\\ b,
|
\\) {
|
||||||
\\ c,
|
\\ a,
|
||||||
\\ _,
|
\\ b,
|
||||||
\\};
|
\\ c,
|
||||||
\\pub const a = @enumToInt(d.a);
|
\\ _,
|
||||||
\\pub const b = @enumToInt(d.b);
|
\\};
|
||||||
\\pub const c = @enumToInt(d.c);
|
\\pub const a = @enumToInt(d.a);
|
||||||
\\const enum_unnamed_1 = extern enum(c_int) {
|
\\pub const b = @enumToInt(d.b);
|
||||||
\\ e = 0,
|
\\pub const c = @enumToInt(d.c);
|
||||||
\\ f = 4,
|
\\const enum_unnamed_1 = extern enum(
|
||||||
\\ g = 5,
|
++ default_enum_type ++
|
||||||
\\ _,
|
\\) {
|
||||||
\\};
|
\\ e = 0,
|
||||||
\\pub const e = @enumToInt(enum_unnamed_1.e);
|
\\ f = 4,
|
||||||
\\pub const f = @enumToInt(enum_unnamed_1.f);
|
\\ g = 5,
|
||||||
\\pub const g = @enumToInt(enum_unnamed_1.g);
|
\\ _,
|
||||||
\\pub export var h: enum_unnamed_1 = @import("std").meta.cast(enum_unnamed_1, e);
|
\\};
|
||||||
\\const enum_unnamed_2 = extern enum(c_int) {
|
\\pub const e = @enumToInt(enum_unnamed_1.e);
|
||||||
\\ i,
|
\\pub const f = @enumToInt(enum_unnamed_1.f);
|
||||||
\\ j,
|
\\pub const g = @enumToInt(enum_unnamed_1.g);
|
||||||
\\ k,
|
\\pub export var h: enum_unnamed_1 = @import("std").meta.cast(enum_unnamed_1, e);
|
||||||
\\ _,
|
\\const enum_unnamed_2 = extern enum(
|
||||||
\\};
|
++ default_enum_type ++
|
||||||
\\pub const i = @enumToInt(enum_unnamed_2.i);
|
\\) {
|
||||||
\\pub const j = @enumToInt(enum_unnamed_2.j);
|
\\ i,
|
||||||
\\pub const k = @enumToInt(enum_unnamed_2.k);
|
\\ j,
|
||||||
\\pub const struct_Baz = extern struct {
|
\\ k,
|
||||||
\\ l: enum_unnamed_2,
|
\\ _,
|
||||||
\\ m: d,
|
\\};
|
||||||
\\};
|
\\pub const i = @enumToInt(enum_unnamed_2.i);
|
||||||
\\pub const enum_i = extern enum(c_int) {
|
\\pub const j = @enumToInt(enum_unnamed_2.j);
|
||||||
\\ n,
|
\\pub const k = @enumToInt(enum_unnamed_2.k);
|
||||||
\\ o,
|
\\pub const struct_Baz = extern struct {
|
||||||
\\ p,
|
\\ l: enum_unnamed_2,
|
||||||
\\ _,
|
\\ m: d,
|
||||||
\\};
|
\\};
|
||||||
\\pub const n = @enumToInt(enum_i.n);
|
\\pub const enum_i = extern enum(
|
||||||
\\pub const o = @enumToInt(enum_i.o);
|
++ default_enum_type ++
|
||||||
\\pub const p = @enumToInt(enum_i.p);
|
\\) {
|
||||||
|
\\ n,
|
||||||
|
\\ o,
|
||||||
|
\\ p,
|
||||||
|
\\ _,
|
||||||
|
\\};
|
||||||
|
\\pub const n = @enumToInt(enum_i.n);
|
||||||
|
\\pub const o = @enumToInt(enum_i.o);
|
||||||
|
\\pub const p = @enumToInt(enum_i.p);
|
||||||
,
|
,
|
||||||
\\pub const Baz = struct_Baz;
|
\\pub const Baz = struct_Baz;
|
||||||
});
|
});
|
||||||
@ -2234,13 +2250,15 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\ Two,
|
\\ Two,
|
||||||
\\};
|
\\};
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
\\const enum_unnamed_1 = extern enum(c_int) {
|
\\const enum_unnamed_1 = extern enum(
|
||||||
\\ One,
|
++ default_enum_type ++
|
||||||
\\ Two,
|
\\) {
|
||||||
\\ _,
|
\\ One,
|
||||||
\\};
|
\\ Two,
|
||||||
\\pub const One = @enumToInt(enum_unnamed_1.One);
|
\\ _,
|
||||||
\\pub const Two = @enumToInt(enum_unnamed_1.Two);
|
\\};
|
||||||
|
\\pub const One = @enumToInt(enum_unnamed_1.One);
|
||||||
|
\\pub const Two = @enumToInt(enum_unnamed_1.Two);
|
||||||
});
|
});
|
||||||
|
|
||||||
cases.add("c style cast",
|
cases.add("c style cast",
|
||||||
@ -2338,35 +2356,37 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);
|
\\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
\\pub const enum_Foo = extern enum(c_int) {
|
\\pub const enum_Foo = extern enum(
|
||||||
\\ A,
|
++ default_enum_type ++
|
||||||
\\ B,
|
\\) {
|
||||||
\\ C,
|
\\ A,
|
||||||
\\ _,
|
\\ B,
|
||||||
\\};
|
\\ C,
|
||||||
\\pub const FooA = @enumToInt(enum_Foo.A);
|
\\ _,
|
||||||
\\pub const FooB = @enumToInt(enum_Foo.B);
|
\\};
|
||||||
\\pub const FooC = @enumToInt(enum_Foo.C);
|
\\pub const FooA = @enumToInt(enum_Foo.A);
|
||||||
\\pub const SomeTypedef = c_int;
|
\\pub const FooB = @enumToInt(enum_Foo.B);
|
||||||
\\pub export fn and_or_non_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void) c_int {
|
\\pub const FooC = @enumToInt(enum_Foo.C);
|
||||||
\\ var a = arg_a;
|
\\pub const SomeTypedef = c_int;
|
||||||
\\ var b = arg_b;
|
\\pub export fn and_or_non_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void) c_int {
|
||||||
\\ var c = arg_c;
|
\\ var a = arg_a;
|
||||||
\\ var d: enum_Foo = @import("std").meta.cast(enum_Foo, FooA);
|
\\ var b = arg_b;
|
||||||
\\ var e: c_int = @boolToInt((a != 0) and (b != 0));
|
\\ var c = arg_c;
|
||||||
\\ var f: c_int = @boolToInt((b != 0) and (c != null));
|
\\ var d: enum_Foo = @import("std").meta.cast(enum_Foo, FooA);
|
||||||
\\ var g: c_int = @boolToInt((a != 0) and (c != null));
|
\\ var e: c_int = @boolToInt((a != 0) and (b != 0));
|
||||||
\\ var h: c_int = @boolToInt((a != 0) or (b != 0));
|
\\ var f: c_int = @boolToInt((b != 0) and (c != null));
|
||||||
\\ var i: c_int = @boolToInt((b != 0) or (c != null));
|
\\ var g: c_int = @boolToInt((a != 0) and (c != null));
|
||||||
\\ var j: c_int = @boolToInt((a != 0) or (c != null));
|
\\ var h: c_int = @boolToInt((a != 0) or (b != 0));
|
||||||
\\ var k: c_int = @boolToInt((a != 0) or (@bitCast(c_int, @enumToInt(d)) != 0));
|
\\ var i: c_int = @boolToInt((b != 0) or (c != null));
|
||||||
\\ var l: c_int = @boolToInt((@bitCast(c_int, @enumToInt(d)) != 0) and (b != 0));
|
\\ var j: c_int = @boolToInt((a != 0) or (c != null));
|
||||||
\\ var m: c_int = @boolToInt((c != null) or (@bitCast(c_uint, @enumToInt(d)) != 0));
|
\\ var k: c_int = @boolToInt((a != 0) or (@bitCast(c_int, @enumToInt(d)) != 0));
|
||||||
\\ var td: SomeTypedef = 44;
|
\\ var l: c_int = @boolToInt((@bitCast(c_int, @enumToInt(d)) != 0) and (b != 0));
|
||||||
\\ var o: c_int = @boolToInt((td != 0) or (b != 0));
|
\\ var m: c_int = @boolToInt((c != null) or (@bitCast(c_uint, @enumToInt(d)) != 0));
|
||||||
\\ var p: c_int = @boolToInt((c != null) and (td != 0));
|
\\ var td: SomeTypedef = 44;
|
||||||
\\ return (((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p;
|
\\ var o: c_int = @boolToInt((td != 0) or (b != 0));
|
||||||
\\}
|
\\ var p: c_int = @boolToInt((c != null) and (td != 0));
|
||||||
|
\\ return (((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p;
|
||||||
|
\\}
|
||||||
,
|
,
|
||||||
\\pub const Foo = enum_Foo;
|
\\pub const Foo = enum_Foo;
|
||||||
});
|
});
|
||||||
@ -2387,14 +2407,16 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\ y: c_int,
|
\\ y: c_int,
|
||||||
\\};
|
\\};
|
||||||
,
|
,
|
||||||
\\pub const enum_Bar = extern enum(c_int) {
|
\\pub const enum_Bar = extern enum(
|
||||||
\\ A,
|
++ default_enum_type ++
|
||||||
\\ B,
|
\\) {
|
||||||
\\ _,
|
\\ A,
|
||||||
\\};
|
\\ B,
|
||||||
\\pub const BarA = @enumToInt(enum_Bar.A);
|
\\ _,
|
||||||
\\pub const BarB = @enumToInt(enum_Bar.B);
|
\\};
|
||||||
\\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void;
|
\\pub const BarA = @enumToInt(enum_Bar.A);
|
||||||
|
\\pub const BarB = @enumToInt(enum_Bar.B);
|
||||||
|
\\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void;
|
||||||
,
|
,
|
||||||
\\pub const Foo = struct_Foo;
|
\\pub const Foo = struct_Foo;
|
||||||
\\pub const Bar = enum_Bar;
|
\\pub const Bar = enum_Bar;
|
||||||
@ -2664,26 +2686,28 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\ return 4;
|
\\ return 4;
|
||||||
\\}
|
\\}
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
\\pub const enum_SomeEnum = extern enum(c_int) {
|
\\pub const enum_SomeEnum = extern enum(
|
||||||
\\ A,
|
++ default_enum_type ++
|
||||||
\\ B,
|
\\) {
|
||||||
\\ C,
|
\\ A,
|
||||||
\\ _,
|
\\ B,
|
||||||
\\};
|
\\ C,
|
||||||
\\pub const A = @enumToInt(enum_SomeEnum.A);
|
\\ _,
|
||||||
\\pub const B = @enumToInt(enum_SomeEnum.B);
|
\\};
|
||||||
\\pub const C = @enumToInt(enum_SomeEnum.C);
|
\\pub const A = @enumToInt(enum_SomeEnum.A);
|
||||||
\\pub export fn if_none_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void, arg_d: enum_SomeEnum) c_int {
|
\\pub const B = @enumToInt(enum_SomeEnum.B);
|
||||||
\\ var a = arg_a;
|
\\pub const C = @enumToInt(enum_SomeEnum.C);
|
||||||
\\ var b = arg_b;
|
\\pub export fn if_none_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void, arg_d: enum_SomeEnum) c_int {
|
||||||
\\ var c = arg_c;
|
\\ var a = arg_a;
|
||||||
\\ var d = arg_d;
|
\\ var b = arg_b;
|
||||||
\\ if (a != 0) return 0;
|
\\ var c = arg_c;
|
||||||
\\ if (b != 0) return 1;
|
\\ var d = arg_d;
|
||||||
\\ if (c != null) return 2;
|
\\ if (a != 0) return 0;
|
||||||
\\ if (@enumToInt(d) != 0) return 3;
|
\\ if (b != 0) return 1;
|
||||||
\\ return 4;
|
\\ if (c != null) return 2;
|
||||||
\\}
|
\\ if (@enumToInt(d) != 0) return 3;
|
||||||
|
\\ return 4;
|
||||||
|
\\}
|
||||||
});
|
});
|
||||||
|
|
||||||
cases.add("simple data types",
|
cases.add("simple data types",
|
||||||
@ -3130,15 +3154,17 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
|
|||||||
\\ Foo1,
|
\\ Foo1,
|
||||||
\\};
|
\\};
|
||||||
, &[_][]const u8{
|
, &[_][]const u8{
|
||||||
\\pub const enum_Foo = extern enum(c_int) {
|
\\pub const enum_Foo = extern enum(
|
||||||
\\ A = 2,
|
++ default_enum_type ++
|
||||||
\\ B = 5,
|
\\) {
|
||||||
\\ @"1" = 6,
|
\\ A = 2,
|
||||||
\\ _,
|
\\ B = 5,
|
||||||
\\};
|
\\ @"1" = 6,
|
||||||
\\pub const FooA = @enumToInt(enum_Foo.A);
|
\\ _,
|
||||||
\\pub const FooB = @enumToInt(enum_Foo.B);
|
\\};
|
||||||
\\pub const Foo1 = @enumToInt(enum_Foo.@"1");
|
\\pub const FooA = @enumToInt(enum_Foo.A);
|
||||||
|
\\pub const FooB = @enumToInt(enum_Foo.B);
|
||||||
|
\\pub const Foo1 = @enumToInt(enum_Foo.@"1");
|
||||||
,
|
,
|
||||||
\\pub const Foo = enum_Foo;
|
\\pub const Foo = enum_Foo;
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user