Skip to content

Commit 832a6ee

Browse files
committed
translate-c: Declare type of enum constants
If the enum type cannot be translated for some reason, omit it. In that case the previous behavior will occur - the enum constant's type will be the enum's tag type. Fixes ziglang#9153
1 parent e006281 commit 832a6ee

File tree

4 files changed

+66
-35
lines changed

4 files changed

+66
-35
lines changed

src/translate_c.zig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,12 +1158,20 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E
11581158
.value = int_node,
11591159
});
11601160

1161+
const enum_const_qt = @ptrCast(*const clang.ValueDecl, enum_const).getType();
1162+
const enum_const_loc = @ptrCast(*const clang.Decl, enum_const).getLocation();
1163+
const enum_const_type_node: ?Node = transQualType(c, scope, enum_const_qt, enum_const_loc) catch |err| switch (err) {
1164+
error.UnsupportedType => null,
1165+
else => |e| return e,
1166+
};
1167+
11611168
// In C each enum value is in the global namespace. So we put them there too.
11621169
// At this point we can rely on the enum emitting successfully.
11631170
try redecls.append(.{
11641171
.enum_val_name = enum_val_name,
11651172
.field_name = field_name,
11661173
.enum_name = name,
1174+
.type = enum_const_type_node,
11671175
});
11681176
}
11691177

@@ -1201,6 +1209,7 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E
12011209
.enum_val_name = try bs.makeMangledName(c, redecl.enum_val_name),
12021210
.field_name = redecl.field_name,
12031211
.enum_name = redecl.enum_name,
1212+
.type = redecl.type,
12041213
}));
12051214
}
12061215
}

src/translate_c/ast.zig

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ pub const Payload = struct {
664664
enum_val_name: []const u8,
665665
field_name: []const u8,
666666
enum_name: []const u8,
667+
type: ?Node,
667668
},
668669
};
669670

@@ -1873,6 +1874,11 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
18731874
if (node.tag() == .pub_enum_redecl) _ = try c.addToken(.keyword_pub, "pub");
18741875
const const_tok = try c.addToken(.keyword_const, "const");
18751876
_ = try c.addIdentifier(payload.enum_val_name);
1877+
const type_node = if (payload.type) |enum_const_type| blk: {
1878+
_ = try c.addToken(.colon, ":");
1879+
break :blk try renderNode(c, enum_const_type);
1880+
} else 0;
1881+
18761882
_ = try c.addToken(.equal, "=");
18771883

18781884
const enum_to_int_tok = try c.addToken(.builtin, "@enumToInt");
@@ -1898,7 +1904,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
18981904
.tag = .simple_var_decl,
18991905
.main_token = const_tok,
19001906
.data = .{
1901-
.lhs = 0,
1907+
.lhs = type_node,
19021908
.rhs = init_node,
19031909
},
19041910
});

test/run_translated_c.zig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1598,4 +1598,20 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
15981598
\\ return 0;
15991599
\\}
16001600
, "");
1601+
1602+
cases.add("Enum constants are assigned correct type. Issue #9153",
1603+
\\enum A { A0, A1=0xFFFFFFFF };
1604+
\\enum B { B0=-1, B1=0xFFFFFFFF };
1605+
\\enum C { C0=-1, C1=0 };
1606+
\\enum D { D0, D1=0xFFFFFFFFFFL };
1607+
\\enum E { E0=-1, E1=0xFFFFFFFFFFL };
1608+
\\int main(void) {
1609+
\\ signed char a0 = A0, a1 = A1;
1610+
\\ signed char b0 = B0, b1 = B1;
1611+
\\ signed char c0 = C0, c1 = C1;
1612+
\\ signed char d0 = D0, d1 = D1;
1613+
\\ signed char e0 = E0, e1 = E1;
1614+
\\ return 0;
1615+
\\}
1616+
, "");
16011617
}

test/translate_c.zig

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3737
\\ B,
3838
\\ _,
3939
\\};
40-
\\pub const FooA = @enumToInt(Foo.A);
41-
\\pub const FooB = @enumToInt(Foo.B);
40+
\\pub const FooA: c_int = @enumToInt(Foo.A);
41+
\\pub const FooB: c_int = @enumToInt(Foo.B);
4242
\\pub const Bar = extern struct {
4343
\\ a: c_int,
4444
\\ b: c_int,
@@ -130,9 +130,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
130130
\\ C,
131131
\\ _,
132132
\\ };
133-
\\ const A = @enumToInt(enum_Foo.A);
134-
\\ const B = @enumToInt(enum_Foo.B);
135-
\\ const C = @enumToInt(enum_Foo.C);
133+
\\ const A: c_int = @enumToInt(enum_Foo.A);
134+
\\ const B: c_int = @enumToInt(enum_Foo.B);
135+
\\ const C: c_int = @enumToInt(enum_Foo.C);
136136
\\ var a: enum_Foo = @import("std").zig.c_translation.cast(enum_Foo, B);
137137
\\ {
138138
\\ const enum_Foo = extern enum(
@@ -143,9 +143,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
143143
\\ C,
144144
\\ _,
145145
\\ };
146-
\\ const A_2 = @enumToInt(enum_Foo.A);
147-
\\ const B_3 = @enumToInt(enum_Foo.B);
148-
\\ const C_4 = @enumToInt(enum_Foo.C);
146+
\\ const A_2: c_int = @enumToInt(enum_Foo.A);
147+
\\ const B_3: c_int = @enumToInt(enum_Foo.B);
148+
\\ const C_4: c_int = @enumToInt(enum_Foo.C);
149149
\\ var a_5: enum_Foo = @import("std").zig.c_translation.cast(enum_Foo, B_3);
150150
\\ }
151151
\\}
@@ -1595,7 +1595,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
15951595
\\ FOO,
15961596
\\ _,
15971597
\\};
1598-
\\pub const FOO = @enumToInt(enum_enum_ty.FOO);
1598+
\\pub const FOO: c_int = @enumToInt(enum_enum_ty.FOO);
15991599
\\pub extern var my_enum: enum_enum_ty;
16001600
});
16011601

@@ -1724,9 +1724,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17241724
\\ c,
17251725
\\ _,
17261726
\\};
1727-
\\pub const a = @enumToInt(d.a);
1728-
\\pub const b = @enumToInt(d.b);
1729-
\\pub const c = @enumToInt(d.c);
1727+
\\pub const a: c_int = @enumToInt(d.a);
1728+
\\pub const b: c_int = @enumToInt(d.b);
1729+
\\pub const c: c_int = @enumToInt(d.c);
17301730
\\const enum_unnamed_1 = extern enum(
17311731
++ default_enum_type ++
17321732
\\) {
@@ -1735,9 +1735,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17351735
\\ g = 5,
17361736
\\ _,
17371737
\\};
1738-
\\pub const e = @enumToInt(enum_unnamed_1.e);
1739-
\\pub const f = @enumToInt(enum_unnamed_1.f);
1740-
\\pub const g = @enumToInt(enum_unnamed_1.g);
1738+
\\pub const e: c_int = @enumToInt(enum_unnamed_1.e);
1739+
\\pub const f: c_int = @enumToInt(enum_unnamed_1.f);
1740+
\\pub const g: c_int = @enumToInt(enum_unnamed_1.g);
17411741
\\pub export var h: enum_unnamed_1 = @import("std").zig.c_translation.cast(enum_unnamed_1, e);
17421742
\\const enum_unnamed_2 = extern enum(
17431743
++ default_enum_type ++
@@ -1747,9 +1747,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17471747
\\ k,
17481748
\\ _,
17491749
\\};
1750-
\\pub const i = @enumToInt(enum_unnamed_2.i);
1751-
\\pub const j = @enumToInt(enum_unnamed_2.j);
1752-
\\pub const k = @enumToInt(enum_unnamed_2.k);
1750+
\\pub const i: c_int = @enumToInt(enum_unnamed_2.i);
1751+
\\pub const j: c_int = @enumToInt(enum_unnamed_2.j);
1752+
\\pub const k: c_int = @enumToInt(enum_unnamed_2.k);
17531753
\\pub const struct_Baz = extern struct {
17541754
\\ l: enum_unnamed_2,
17551755
\\ m: d,
@@ -1762,9 +1762,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
17621762
\\ p,
17631763
\\ _,
17641764
\\};
1765-
\\pub const n = @enumToInt(enum_i.n);
1766-
\\pub const o = @enumToInt(enum_i.o);
1767-
\\pub const p = @enumToInt(enum_i.p);
1765+
\\pub const n: c_int = @enumToInt(enum_i.n);
1766+
\\pub const o: c_int = @enumToInt(enum_i.o);
1767+
\\pub const p: c_int = @enumToInt(enum_i.p);
17681768
,
17691769
\\pub const Baz = struct_Baz;
17701770
});
@@ -2264,8 +2264,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
22642264
\\ Two,
22652265
\\ _,
22662266
\\};
2267-
\\pub const One = @enumToInt(enum_unnamed_1.One);
2268-
\\pub const Two = @enumToInt(enum_unnamed_1.Two);
2267+
\\pub const One: c_int = @enumToInt(enum_unnamed_1.One);
2268+
\\pub const Two: c_int = @enumToInt(enum_unnamed_1.Two);
22692269
});
22702270

22712271
cases.add("c style cast",
@@ -2371,9 +2371,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
23712371
\\ C,
23722372
\\ _,
23732373
\\};
2374-
\\pub const FooA = @enumToInt(enum_Foo.A);
2375-
\\pub const FooB = @enumToInt(enum_Foo.B);
2376-
\\pub const FooC = @enumToInt(enum_Foo.C);
2374+
\\pub const FooA: c_int = @enumToInt(enum_Foo.A);
2375+
\\pub const FooB: c_int = @enumToInt(enum_Foo.B);
2376+
\\pub const FooC: c_int = @enumToInt(enum_Foo.C);
23772377
\\pub const SomeTypedef = c_int;
23782378
\\pub export fn and_or_non_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void) c_int {
23792379
\\ var a = arg_a;
@@ -2421,8 +2421,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
24212421
\\ B,
24222422
\\ _,
24232423
\\};
2424-
\\pub const BarA = @enumToInt(enum_Bar.A);
2425-
\\pub const BarB = @enumToInt(enum_Bar.B);
2424+
\\pub const BarA: c_int = @enumToInt(enum_Bar.A);
2425+
\\pub const BarB: c_int = @enumToInt(enum_Bar.B);
24262426
\\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void;
24272427
,
24282428
\\pub const Foo = struct_Foo;
@@ -2701,9 +2701,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
27012701
\\ C,
27022702
\\ _,
27032703
\\};
2704-
\\pub const A = @enumToInt(enum_SomeEnum.A);
2705-
\\pub const B = @enumToInt(enum_SomeEnum.B);
2706-
\\pub const C = @enumToInt(enum_SomeEnum.C);
2704+
\\pub const A: c_int = @enumToInt(enum_SomeEnum.A);
2705+
\\pub const B: c_int = @enumToInt(enum_SomeEnum.B);
2706+
\\pub const C: c_int = @enumToInt(enum_SomeEnum.C);
27072707
\\pub export fn if_none_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void, arg_d: enum_SomeEnum) c_int {
27082708
\\ var a = arg_a;
27092709
\\ var b = arg_b;
@@ -3169,9 +3169,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
31693169
\\ @"1" = 6,
31703170
\\ _,
31713171
\\};
3172-
\\pub const FooA = @enumToInt(enum_Foo.A);
3173-
\\pub const FooB = @enumToInt(enum_Foo.B);
3174-
\\pub const Foo1 = @enumToInt(enum_Foo.@"1");
3172+
\\pub const FooA: c_int = @enumToInt(enum_Foo.A);
3173+
\\pub const FooB: c_int = @enumToInt(enum_Foo.B);
3174+
\\pub const Foo1: c_int = @enumToInt(enum_Foo.@"1");
31753175
,
31763176
\\pub const Foo = enum_Foo;
31773177
});

0 commit comments

Comments
 (0)