diff --git a/src-self-hosted/translate_c.zig b/src-self-hosted/translate_c.zig index 1539417cb..0b8fabc6c 100644 --- a/src-self-hosted/translate_c.zig +++ b/src-self-hosted/translate_c.zig @@ -898,11 +898,25 @@ fn transEnumDecl(c: *Context, enum_decl: *const ZigClangEnumDecl) Error!?*ast.No try container_node.fields_and_decls.push(&field_node.base); _ = try appendToken(c, .Comma, ","); + // In C each enum value is in the global namespace. So we put them there too. // At this point we can rely on the enum emitting successfully. const tld_node = try transCreateNodeVarDecl(c, true, true, enum_val_name); tld_node.eq_token = try appendToken(c, .Equal, "="); - tld_node.init_node = try transCreateNodeAPInt(c, ZigClangEnumConstantDecl_getInitVal(enum_const)); + const cast_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt"); + const enum_ident = try transCreateNodeIdentifier(c, name); + const period_tok = try appendToken(c, .Period, "."); + const field_ident = try transCreateNodeIdentifier(c, field_name); + const field_access_node = try c.a().create(ast.Node.InfixOp); + field_access_node.* = .{ + .op_token = period_tok, + .lhs = enum_ident, + .op = .Period, + .rhs = field_ident, + }; + try cast_node.params.push(&field_access_node.base); + cast_node.rparen_token = try appendToken(rp.c, .RParen, ")"); + tld_node.init_node = &cast_node.base; tld_node.semicolon_token = try appendToken(c, .Semicolon, ";"); try addTopLevelDecl(c, field_name, &tld_node.base); } @@ -1712,15 +1726,7 @@ fn transCCast( builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); return &builtin_node.base; } - if (ZigClangQualType_getTypeClass(src_type) == .Elaborated) { - const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ZigClangQualType_getTypePtr(src_type)); - return transCCast(rp, scope, loc, dst_type, ZigClangElaboratedType_getNamedType(elaborated_ty), expr); - } - if (ZigClangQualType_getTypeClass(dst_type) == .Elaborated) { - const elaborated_ty = @ptrCast(*const ZigClangElaboratedType, ZigClangQualType_getTypePtr(dst_type)); - return transCCast(rp, scope, loc, ZigClangElaboratedType_getNamedType(elaborated_ty), src_type, expr); - } - if (ZigClangQualType_getTypeClass(dst_type) == .Enum) { + if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) == .Enum) { const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@intToEnum"); try builtin_node.params.push(try transQualType(rp, dst_type, loc)); _ = try appendToken(rp.c, .Comma, ","); @@ -1728,8 +1734,8 @@ fn transCCast( builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")"); return &builtin_node.base; } - if (ZigClangQualType_getTypeClass(src_type) == .Enum and - ZigClangQualType_getTypeClass(dst_type) != .Enum) + if (ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(src_type)) == .Enum and + ZigClangQualType_getTypeClass(ZigClangQualType_getCanonicalType(dst_type)) != .Enum) { const builtin_node = try transCreateNodeBuiltinFnCall(rp.c, "@enumToInt"); try builtin_node.params.push(expr); diff --git a/test/translate_c.zig b/test/translate_c.zig index 63c477f35..0299da7b7 100644 --- a/test/translate_c.zig +++ b/test/translate_c.zig @@ -912,7 +912,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\extern enum enum_ty my_enum; \\enum enum_ty { FOO }; , &[_][]const u8{ - \\pub const FOO = 0; + \\pub const FOO = @enumToInt(enum_enum_ty.FOO); \\pub const enum_enum_ty = extern enum { \\ FOO, \\}; @@ -990,27 +990,27 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ p, \\}; , &[_][]const u8{ - \\pub const a = 0; - \\pub const b = 1; - \\pub const c = 2; + \\pub const a = @enumToInt(enum_unnamed_1.a); + \\pub const b = @enumToInt(enum_unnamed_1.b); + \\pub const c = @enumToInt(enum_unnamed_1.c); \\const enum_unnamed_1 = extern enum { \\ a, \\ b, \\ c, \\}; \\pub const d = enum_unnamed_1; - \\pub const e = 0; - \\pub const f = 4; - \\pub const g = 5; + \\pub const e = @enumToInt(enum_unnamed_2.e); + \\pub const f = @enumToInt(enum_unnamed_2.f); + \\pub const g = @enumToInt(enum_unnamed_2.g); \\const enum_unnamed_2 = extern enum { \\ e = 0, \\ f = 4, \\ g = 5, \\}; \\pub export var h: enum_unnamed_2 = @intToEnum(enum_unnamed_2, e); - \\pub const i = 0; - \\pub const j = 1; - \\pub const k = 2; + \\pub const i = @enumToInt(enum_unnamed_3.i); + \\pub const j = @enumToInt(enum_unnamed_3.j); + \\pub const k = @enumToInt(enum_unnamed_3.k); \\const enum_unnamed_3 = extern enum { \\ i, \\ j, @@ -1020,9 +1020,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ l: enum_unnamed_3, \\ m: d, \\}; - \\pub const n = 0; - \\pub const o = 1; - \\pub const p = 2; + \\pub const n = @enumToInt(enum_i.n); + \\pub const o = @enumToInt(enum_i.o); + \\pub const p = @enumToInt(enum_i.p); \\pub const enum_i = extern enum { \\ n, \\ o, @@ -1448,8 +1448,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ Two, \\}; , &[_][]const u8{ - \\pub const One = 0; - \\pub const Two = 1; + \\pub const One = @enumToInt(enum_unnamed_1.One); + \\pub const Two = @enumToInt(enum_unnamed_1.Two); \\const enum_unnamed_1 = extern enum { \\ One, \\ Two, @@ -2252,28 +2252,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\pub const FOO_CHAR = '\x3f'; }); - cases.add("enums", - \\enum Foo { - \\ FooA, - \\ FooB, - \\ Foo1, - \\}; - , &[_][]const u8{ - \\pub const enum_Foo = extern enum { - \\ A, - \\ B, - \\ @"1", - \\}; - , - \\pub const FooA = 0; - , - \\pub const FooB = 1; - , - \\pub const Foo1 = 2; - , - \\pub const Foo = enum_Foo; - }); - cases.add("enums", \\enum Foo { \\ FooA = 2, @@ -2281,17 +2259,14 @@ pub fn addCases(cases: *tests.TranslateCContext) void { \\ Foo1, \\}; , &[_][]const u8{ + \\pub const FooA = @enumToInt(enum_Foo.A); + \\pub const FooB = @enumToInt(enum_Foo.B); + \\pub const Foo1 = @enumToInt(enum_Foo.@"1"); \\pub const enum_Foo = extern enum { \\ A = 2, \\ B = 5, \\ @"1" = 6, \\}; - , - \\pub const FooA = 2; - , - \\pub const FooB = 5; - , - \\pub const Foo1 = 6; , \\pub const Foo = enum_Foo; });