authorgravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2021-06-18 17:36:50-07:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-06-23 08:44:25+03:00
log0e7897a9a2e8dff1ce869b78d5b6fda56f86bb05
treeee37a14f5b1d6a7a06eb5860d87d3eda9403035d
parentd1f99eabb745a3026b4bf0486ee542d38facee8b

translate-c: Remove usage of `extern enum`

Translate enum types as the underlying integer type. Translate enum constants as top-level integer constants of the correct type (which does not necessarily match the enum integer type). If an enum constant's type cannot be translated for some reason, omit it. See discussion https://github.com/ziglang/zig/issues/2115#issuecomment-827968279 Fixes #9153

8 files changed, 198 insertions(+), 435 deletions(-)

lib/std/zig/c_translation.zig+2-35
...@@ -11,7 +11,7 @@ const mem = std.mem;...@@ -11,7 +11,7 @@ const mem = std.mem;
1111
12/// Given a type and value, cast the value to the type as c would.12/// Given a type and value, cast the value to the type as c would.
13pub fn cast(comptime DestType: type, target: anytype) DestType {13pub fn cast(comptime DestType: type, target: anytype) DestType {
14 // this function should behave like transCCast in translate-c, except it's for macros and enums14 // this function should behave like transCCast in translate-c, except it's for macros
15 const SourceType = @TypeOf(target);15 const SourceType = @TypeOf(target);
16 switch (@typeInfo(DestType)) {16 switch (@typeInfo(DestType)) {
17 .Fn, .Pointer => return castToPtr(DestType, SourceType, target),17 .Fn, .Pointer => return castToPtr(DestType, SourceType, target),
...@@ -20,12 +20,6 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {...@@ -20,12 +20,6 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
20 return castToPtr(DestType, SourceType, target);20 return castToPtr(DestType, SourceType, target);
21 }21 }
22 },22 },
23 .Enum => |enum_type| {
24 if (@typeInfo(SourceType) == .Int or @typeInfo(SourceType) == .ComptimeInt) {
25 const intermediate = cast(enum_type.tag_type, target);
26 return @intToEnum(DestType, intermediate);
27 }
28 },
29 .Int => {23 .Int => {
30 switch (@typeInfo(SourceType)) {24 switch (@typeInfo(SourceType)) {
31 .Pointer => {25 .Pointer => {
...@@ -36,9 +30,6 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {...@@ -36,9 +30,6 @@ pub fn cast(comptime DestType: type, target: anytype) DestType {
36 return castInt(DestType, @ptrToInt(target));30 return castInt(DestType, @ptrToInt(target));
37 }31 }
38 },32 },
39 .Enum => {
40 return castInt(DestType, @enumToInt(target));
41 },
42 .Int => {33 .Int => {
43 return castInt(DestType, target);34 return castInt(DestType, target);
44 },35 },
...@@ -106,12 +97,6 @@ fn ptrInfo(comptime PtrType: type) std.builtin.TypeInfo.Pointer {...@@ -106,12 +97,6 @@ fn ptrInfo(comptime PtrType: type) std.builtin.TypeInfo.Pointer {
106}97}
10798
108test "cast" {99test "cast" {
109 const E = enum(u2) {
110 Zero,
111 One,
112 Two,
113 };
114
115 var i = @as(i64, 10);100 var i = @as(i64, 10);
116101
117 try testing.expect(cast(*u8, 16) == @intToPtr(*u8, 16));102 try testing.expect(cast(*u8, 16) == @intToPtr(*u8, 16));
...@@ -122,12 +107,9 @@ test "cast" {...@@ -122,12 +107,9 @@ test "cast" {
122 try testing.expect(cast(?*i64, @as(*align(1) i64, &i)) == &i);107 try testing.expect(cast(?*i64, @as(*align(1) i64, &i)) == &i);
123 try testing.expect(cast(?*i64, @as(?*align(1) i64, &i)) == &i);108 try testing.expect(cast(?*i64, @as(?*align(1) i64, &i)) == &i);
124109
125 try testing.expect(cast(E, 1) == .One);
126
127 try testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(*u32, 4)));110 try testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(*u32, 4)));
128 try testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(?*u32, 4)));111 try testing.expectEqual(@as(u32, 4), cast(u32, @intToPtr(?*u32, 4)));
129 try testing.expectEqual(@as(u32, 10), cast(u32, @as(u64, 10)));112 try testing.expectEqual(@as(u32, 10), cast(u32, @as(u64, 10)));
130 try testing.expectEqual(@as(u8, 2), cast(u8, E.Two));
131113
132 try testing.expectEqual(@bitCast(i32, @as(u32, 0x8000_0000)), cast(i32, @as(u32, 0x8000_0000)));114 try testing.expectEqual(@bitCast(i32, @as(u32, 0x8000_0000)), cast(i32, @as(u32, 0x8000_0000)));
133115
...@@ -136,17 +118,6 @@ test "cast" {...@@ -136,17 +118,6 @@ test "cast" {
136118
137 try testing.expectEqual(@intToPtr(?*c_void, 2), cast(?*c_void, @intToPtr(*u8, 2)));119 try testing.expectEqual(@intToPtr(?*c_void, 2), cast(?*c_void, @intToPtr(*u8, 2)));
138120
139 const C_ENUM = enum(c_int) {
140 A = 0,
141 B,
142 C,
143 _,
144 };
145 try testing.expectEqual(cast(C_ENUM, @as(i64, -1)), @intToEnum(C_ENUM, -1));
146 try testing.expectEqual(cast(C_ENUM, @as(i8, 1)), .B);
147 try testing.expectEqual(cast(C_ENUM, @as(u64, 1)), .B);
148 try testing.expectEqual(cast(C_ENUM, @as(u64, 42)), @intToEnum(C_ENUM, 42));
149
150 var foo: c_int = -1;121 var foo: c_int = -1;
151 try testing.expect(cast(*c_void, -1) == @intToPtr(*c_void, @bitCast(usize, @as(isize, -1))));122 try testing.expect(cast(*c_void, -1) == @intToPtr(*c_void, @bitCast(usize, @as(isize, -1))));
152 try testing.expect(cast(*c_void, foo) == @intToPtr(*c_void, @bitCast(usize, @as(isize, -1))));123 try testing.expect(cast(*c_void, foo) == @intToPtr(*c_void, @bitCast(usize, @as(isize, -1))));
...@@ -162,7 +133,7 @@ test "cast" {...@@ -162,7 +133,7 @@ test "cast" {
162pub fn sizeof(target: anytype) usize {133pub fn sizeof(target: anytype) usize {
163 const T: type = if (@TypeOf(target) == type) target else @TypeOf(target);134 const T: type = if (@TypeOf(target) == type) target else @TypeOf(target);
164 switch (@typeInfo(T)) {135 switch (@typeInfo(T)) {
165 .Float, .Int, .Struct, .Union, .Enum, .Array, .Bool, .Vector => return @sizeOf(T),136 .Float, .Int, .Struct, .Union, .Array, .Bool, .Vector => return @sizeOf(T),
166 .Fn => {137 .Fn => {
167 // sizeof(main) returns 1, sizeof(&main) returns pointer size.138 // sizeof(main) returns 1, sizeof(&main) returns pointer size.
168 // We cannot distinguish those types in Zig, so use pointer size.139 // We cannot distinguish those types in Zig, so use pointer size.
...@@ -228,7 +199,6 @@ pub fn sizeof(target: anytype) usize {...@@ -228,7 +199,6 @@ pub fn sizeof(target: anytype) usize {
228}199}
229200
230test "sizeof" {201test "sizeof" {
231 const E = enum(c_int) { One, _ };
232 const S = extern struct { a: u32 };202 const S = extern struct { a: u32 };
233203
234 const ptr_size = @sizeOf(*c_void);204 const ptr_size = @sizeOf(*c_void);
...@@ -239,9 +209,6 @@ test "sizeof" {...@@ -239,9 +209,6 @@ test "sizeof" {
239209
240 try testing.expect(sizeof(2.0) == @sizeOf(f64));210 try testing.expect(sizeof(2.0) == @sizeOf(f64));
241211
242 try testing.expect(sizeof(E) == @sizeOf(c_int));
243 try testing.expect(sizeof(E.One) == @sizeOf(c_int));
244
245 try testing.expect(sizeof(S) == 4);212 try testing.expect(sizeof(S) == 4);
246213
247 try testing.expect(sizeof([_]u32{ 4, 5, 6 }) == 12);214 try testing.expect(sizeof([_]u32{ 4, 5, 6 }) == 12);
src/clang.zig-3
...@@ -389,9 +389,6 @@ pub const ElaboratedType = opaque {...@@ -389,9 +389,6 @@ pub const ElaboratedType = opaque {
389};389};
390390
391pub const EnumConstantDecl = opaque {391pub const EnumConstantDecl = opaque {
392 pub const getInitExpr = ZigClangEnumConstantDecl_getInitExpr;
393 extern fn ZigClangEnumConstantDecl_getInitExpr(*const EnumConstantDecl) ?*const Expr;
394
395 pub const getInitVal = ZigClangEnumConstantDecl_getInitVal;392 pub const getInitVal = ZigClangEnumConstantDecl_getInitVal;
396 extern fn ZigClangEnumConstantDecl_getInitVal(*const EnumConstantDecl) *const APSInt;393 extern fn ZigClangEnumConstantDecl_getInitVal(*const EnumConstantDecl) *const APSInt;
397};394};
src/translate_c.zig+35-80
...@@ -1100,27 +1100,37 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E...@@ -1100,27 +1100,37 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E
1100 }1100 }
1101 name = try std.fmt.allocPrint(c.arena, "enum_{s}", .{bare_name});1101 name = try std.fmt.allocPrint(c.arena, "enum_{s}", .{bare_name});
1102 }1102 }
1103 if (!toplevel) _ = try bs.makeMangledName(c, name);1103 if (!toplevel) name = try bs.makeMangledName(c, name);
1104 try c.decl_table.putNoClobber(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), name);1104 try c.decl_table.putNoClobber(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), name);
11051105
1106 const is_pub = toplevel and !is_unnamed;1106 const enum_type_node = if (enum_decl.getDefinition()) |enum_def| blk: {
1107 var redecls = std.ArrayList(Tag.enum_redecl.Data()).init(c.gpa);
1108 defer redecls.deinit();
1109
1110 const init_node = if (enum_decl.getDefinition()) |enum_def| blk: {
1111 var pure_enum = true;
1112 var it = enum_def.enumerator_begin();1107 var it = enum_def.enumerator_begin();
1113 var end_it = enum_def.enumerator_end();1108 const end_it = enum_def.enumerator_end();
1114 while (it.neq(end_it)) : (it = it.next()) {1109 while (it.neq(end_it)) : (it = it.next()) {
1115 const enum_const = it.deref();1110 const enum_const = it.deref();
1116 if (enum_const.getInitExpr()) |_| {1111 var enum_val_name: []const u8 = try c.str(@ptrCast(*const clang.NamedDecl, enum_const).getName_bytes_begin());
1117 pure_enum = false;1112 if (!toplevel) {
1118 break;1113 enum_val_name = try bs.makeMangledName(c, enum_val_name);
1119 }1114 }
1120 }
11211115
1122 var fields = std.ArrayList(ast.Payload.Enum.Field).init(c.gpa);1116 const enum_const_qt = @ptrCast(*const clang.ValueDecl, enum_const).getType();
1123 defer fields.deinit();1117 const enum_const_loc = @ptrCast(*const clang.Decl, enum_const).getLocation();
1118 const enum_const_type_node: ?Node = transQualType(c, scope, enum_const_qt, enum_const_loc) catch |err| switch (err) {
1119 error.UnsupportedType => null,
1120 else => |e| return e,
1121 };
1122
1123 const enum_const_def = try Tag.enum_constant.create(c.arena, .{
1124 .name = enum_val_name,
1125 .is_public = toplevel,
1126 .type = enum_const_type_node,
1127 .value = try transCreateNodeAPInt(c, enum_const.getInitVal()),
1128 });
1129 if (toplevel)
1130 try addTopLevelDecl(c, enum_val_name, enum_const_def)
1131 else
1132 try scope.appendNode(enum_const_def);
1133 }
11241134
1125 const int_type = enum_decl.getIntegerType();1135 const int_type = enum_decl.getIntegerType();
1126 // The underlying type may be null in case of forward-declared enum1136 // The underlying type may be null in case of forward-declared enum
...@@ -1128,61 +1138,27 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E...@@ -1128,61 +1138,27 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E
1128 // default to the usual integer type used for all the enums.1138 // default to the usual integer type used for all the enums.
11291139
1130 // default to c_int since msvc and gcc default to different types1140 // default to c_int since msvc and gcc default to different types
1131 const init_arg_expr = if (int_type.ptr != null)1141 break :blk if (int_type.ptr != null)
1132 transQualType(c, scope, int_type, enum_loc) catch |err| switch (err) {1142 transQualType(c, scope, int_type, enum_loc) catch |err| switch (err) {
1133 error.UnsupportedType => {1143 error.UnsupportedType => {
1134 return failDecl(c, enum_loc, name, "unable to translate enum tag type", .{});1144 return failDecl(c, enum_loc, name, "unable to translate enum integer type", .{});
1135 },1145 },
1136 else => |e| return e,1146 else => |e| return e,
1137 }1147 }
1138 else1148 else
1139 try Tag.type.create(c.arena, "c_int");1149 try Tag.type.create(c.arena, "c_int");
1140
1141 it = enum_def.enumerator_begin();
1142 end_it = enum_def.enumerator_end();
1143 while (it.neq(end_it)) : (it = it.next()) {
1144 const enum_const = it.deref();
1145 const enum_val_name = try c.str(@ptrCast(*const clang.NamedDecl, enum_const).getName_bytes_begin());
1146
1147 const field_name = if (!is_unnamed and mem.startsWith(u8, enum_val_name, bare_name))
1148 enum_val_name[bare_name.len..]
1149 else
1150 enum_val_name;
1151
1152 const int_node = if (!pure_enum)
1153 try transCreateNodeAPInt(c, enum_const.getInitVal())
1154 else
1155 null;
1156
1157 try fields.append(.{
1158 .name = field_name,
1159 .value = int_node,
1160 });
1161
1162 // In C each enum value is in the global namespace. So we put them there too.
1163 // At this point we can rely on the enum emitting successfully.
1164 try redecls.append(.{
1165 .enum_val_name = enum_val_name,
1166 .field_name = field_name,
1167 .enum_name = name,
1168 });
1169 }
1170
1171 break :blk try Tag.@"enum".create(c.arena, .{
1172 .int_type = init_arg_expr,
1173 .fields = try c.arena.dupe(ast.Payload.Enum.Field, fields.items),
1174 });
1175 } else blk: {1150 } else blk: {
1176 try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {});1151 try c.opaque_demotes.put(c.gpa, @ptrToInt(enum_decl.getCanonicalDecl()), {});
1177 break :blk Tag.opaque_literal.init();1152 break :blk Tag.opaque_literal.init();
1178 };1153 };
11791154
1155 const is_pub = toplevel and !is_unnamed;
1180 const payload = try c.arena.create(ast.Payload.SimpleVarDecl);1156 const payload = try c.arena.create(ast.Payload.SimpleVarDecl);
1181 payload.* = .{1157 payload.* = .{
1182 .base = .{ .tag = ([2]Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] },1158 .base = .{ .tag = ([2]Tag{ .var_simple, .pub_var_simple })[@boolToInt(is_pub)] },
1183 .data = .{1159 .data = .{
1160 .init = enum_type_node,
1184 .name = name,1161 .name = name,
1185 .init = init_node,
1186 },1162 },
1187 };1163 };
11881164
...@@ -1193,18 +1169,6 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E...@@ -1193,18 +1169,6 @@ fn transEnumDecl(c: *Context, scope: *Scope, enum_decl: *const clang.EnumDecl) E
1193 } else {1169 } else {
1194 try scope.appendNode(Node.initPayload(&payload.base));1170 try scope.appendNode(Node.initPayload(&payload.base));
1195 }1171 }
1196
1197 for (redecls.items) |redecl| {
1198 if (toplevel) {
1199 try addTopLevelDecl(c, redecl.field_name, try Tag.pub_enum_redecl.create(c.arena, redecl));
1200 } else {
1201 try scope.appendNode(try Tag.enum_redecl.create(c.arena, .{
1202 .enum_val_name = try bs.makeMangledName(c, redecl.enum_val_name),
1203 .field_name = redecl.field_name,
1204 .enum_name = redecl.enum_name,
1205 }));
1206 }
1207 }
1208}1172}
12091173
1210const ResultUsed = enum {1174const ResultUsed = enum {
...@@ -2098,8 +2062,7 @@ fn finishBoolExpr(...@@ -2098,8 +2062,7 @@ fn finishBoolExpr(
2098 },2062 },
2099 .Enum => {2063 .Enum => {
2100 // node != 02064 // node != 0
2101 const int_val = try Tag.enum_to_int.create(c.arena, node);2065 return Tag.not_equal.create(c.arena, .{ .lhs = node, .rhs = Tag.zero_literal.init() });
2102 return Tag.not_equal.create(c.arena, .{ .lhs = int_val, .rhs = Tag.zero_literal.init() });
2103 },2066 },
2104 .Elaborated => {2067 .Elaborated => {
2105 const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty);2068 const elaborated_ty = @ptrCast(*const clang.ElaboratedType, ty);
...@@ -2312,21 +2275,22 @@ fn transCCast(...@@ -2312,21 +2275,22 @@ fn transCCast(
2312 if (dst_type.eq(src_type)) return expr;2275 if (dst_type.eq(src_type)) return expr;
2313 if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type))2276 if (qualTypeIsPtr(dst_type) and qualTypeIsPtr(src_type))
2314 return transCPtrCast(c, scope, loc, dst_type, src_type, expr);2277 return transCPtrCast(c, scope, loc, dst_type, src_type, expr);
2278 if (cIsEnum(dst_type)) return transCCast(c, scope, loc, cIntTypeForEnum(dst_type), src_type, expr);
2279 if (cIsEnum(src_type)) return transCCast(c, scope, loc, dst_type, cIntTypeForEnum(src_type), expr);
23152280
2316 const dst_node = try transQualType(c, scope, dst_type, loc);2281 const dst_node = try transQualType(c, scope, dst_type, loc);
2317 if (cIsInteger(dst_type) and (cIsInteger(src_type) or cIsEnum(src_type))) {2282 if (cIsInteger(dst_type) and cIsInteger(src_type)) {
2318 // 1. If src_type is an enum, determine the underlying signed int type2283 // 1. If src_type is an enum, determine the underlying signed int type
2319 // 2. Extend or truncate without changing signed-ness.2284 // 2. Extend or truncate without changing signed-ness.
2320 // 3. Bit-cast to correct signed-ness2285 // 3. Bit-cast to correct signed-ness
2321 const src_int_type = if (cIsInteger(src_type)) src_type else cIntTypeForEnum(src_type);2286 const src_type_is_signed = cIsSignedInteger(src_type);
2322 const src_type_is_signed = cIsSignedInteger(src_int_type);2287 var src_int_expr = expr;
2323 var src_int_expr = if (cIsInteger(src_type)) expr else try Tag.enum_to_int.create(c.arena, expr);
23242288
2325 if (isBoolRes(src_int_expr)) {2289 if (isBoolRes(src_int_expr)) {
2326 src_int_expr = try Tag.bool_to_int.create(c.arena, src_int_expr);2290 src_int_expr = try Tag.bool_to_int.create(c.arena, src_int_expr);
2327 }2291 }
23282292
2329 switch (cIntTypeCmp(dst_type, src_int_type)) {2293 switch (cIntTypeCmp(dst_type, src_type)) {
2330 .lt => {2294 .lt => {
2331 // @truncate(SameSignSmallerInt, src_int_expr)2295 // @truncate(SameSignSmallerInt, src_int_expr)
2332 const ty_node = try transQualTypeIntWidthOf(c, dst_type, src_type_is_signed);2296 const ty_node = try transQualTypeIntWidthOf(c, dst_type, src_type_is_signed);
...@@ -2379,14 +2343,6 @@ fn transCCast(...@@ -2379,14 +2343,6 @@ fn transCCast(
2379 const bool_to_int = try Tag.bool_to_int.create(c.arena, expr);2343 const bool_to_int = try Tag.bool_to_int.create(c.arena, expr);
2380 return Tag.as.create(c.arena, .{ .lhs = dst_node, .rhs = bool_to_int });2344 return Tag.as.create(c.arena, .{ .lhs = dst_node, .rhs = bool_to_int });
2381 }2345 }
2382 if (cIsEnum(dst_type)) {
2383 // import("std").meta.cast(dest_type, val)
2384 return Tag.helpers_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
2385 }
2386 if (cIsEnum(src_type) and !cIsEnum(dst_type)) {
2387 // @enumToInt(val)
2388 return Tag.enum_to_int.create(c.arena, expr);
2389 }
2390 // @as(dest_type, val)2346 // @as(dest_type, val)
2391 return Tag.as.create(c.arena, .{ .lhs = dst_node, .rhs = expr });2347 return Tag.as.create(c.arena, .{ .lhs = dst_node, .rhs = expr });
2392}2348}
...@@ -5975,7 +5931,6 @@ fn getContainer(c: *Context, node: Node) ?Node {...@@ -5975,7 +5931,6 @@ fn getContainer(c: *Context, node: Node) ?Node {
5975 switch (node.tag()) {5931 switch (node.tag()) {
5976 .@"union",5932 .@"union",
5977 .@"struct",5933 .@"struct",
5978 .@"enum",
5979 .address_of,5934 .address_of,
5980 .bit_not,5935 .bit_not,
5981 .not,5936 .not,
src/translate_c/ast.zig+22-119
...@@ -64,8 +64,6 @@ pub const Node = extern union {...@@ -64,8 +64,6 @@ pub const Node = extern union {
64 static_local_var,64 static_local_var,
65 func,65 func,
66 warning,66 warning,
67 /// All enums are non-exhaustive
68 @"enum",
69 @"struct",67 @"struct",
70 @"union",68 @"union",
71 @"comptime",69 @"comptime",
...@@ -146,10 +144,6 @@ pub const Node = extern union {...@@ -146,10 +144,6 @@ pub const Node = extern union {
146 float_to_int,144 float_to_int,
147 /// @intToFloat(lhs, rhs)145 /// @intToFloat(lhs, rhs)
148 int_to_float,146 int_to_float,
149 /// @intToEnum(lhs, rhs)
150 int_to_enum,
151 /// @enumToInt(operand)
152 enum_to_int,
153 /// @intToPtr(lhs, rhs)147 /// @intToPtr(lhs, rhs)
154 int_to_ptr,148 int_to_ptr,
155 /// @ptrToInt(operand)149 /// @ptrToInt(operand)
...@@ -215,9 +209,8 @@ pub const Node = extern union {...@@ -215,9 +209,8 @@ pub const Node = extern union {
215 var_simple,209 var_simple,
216 /// pub const name = init;210 /// pub const name = init;
217 pub_var_simple,211 pub_var_simple,
218 /// pub const enum_field_name = @enumToInt(enum_name.field_name);212 /// pub? const name (: type)? = value
219 pub_enum_redecl,213 enum_constant,
220 enum_redecl,
221214
222 /// pub inline fn name(params) return_type body215 /// pub inline fn name(params) return_type body
223 pub_inline_fn,216 pub_inline_fn,
...@@ -266,7 +259,6 @@ pub const Node = extern union {...@@ -266,7 +259,6 @@ pub const Node = extern union {
266 .unwrap,259 .unwrap,
267 .deref,260 .deref,
268 .ptr_to_int,261 .ptr_to_int,
269 .enum_to_int,
270 .empty_array,262 .empty_array,
271 .while_true,263 .while_true,
272 .if_not_break,264 .if_not_break,
...@@ -324,7 +316,6 @@ pub const Node = extern union {...@@ -324,7 +316,6 @@ pub const Node = extern union {
324 .float_cast,316 .float_cast,
325 .float_to_int,317 .float_to_int,
326 .int_to_float,318 .int_to_float,
327 .int_to_enum,
328 .int_to_ptr,319 .int_to_ptr,
329 .array_cat,320 .array_cat,
330 .ellipsis3,321 .ellipsis3,
...@@ -357,7 +348,6 @@ pub const Node = extern union {...@@ -357,7 +348,6 @@ pub const Node = extern union {
357 .call => Payload.Call,348 .call => Payload.Call,
358 .var_decl => Payload.VarDecl,349 .var_decl => Payload.VarDecl,
359 .func => Payload.Func,350 .func => Payload.Func,
360 .@"enum" => Payload.Enum,
361 .@"struct", .@"union" => Payload.Record,351 .@"struct", .@"union" => Payload.Record,
362 .tuple => Payload.TupleInit,352 .tuple => Payload.TupleInit,
363 .container_init => Payload.ContainerInit,353 .container_init => Payload.ContainerInit,
...@@ -369,7 +359,7 @@ pub const Node = extern union {...@@ -369,7 +359,7 @@ pub const Node = extern union {
369 .arg_redecl, .alias, .fail_decl => Payload.ArgRedecl,359 .arg_redecl, .alias, .fail_decl => Payload.ArgRedecl,
370 .log2_int_type => Payload.Log2IntType,360 .log2_int_type => Payload.Log2IntType,
371 .var_simple, .pub_var_simple, .static_local_var => Payload.SimpleVarDecl,361 .var_simple, .pub_var_simple, .static_local_var => Payload.SimpleVarDecl,
372 .pub_enum_redecl, .enum_redecl => Payload.EnumRedecl,362 .enum_constant => Payload.EnumConstant,
373 .array_filler => Payload.ArrayFiller,363 .array_filler => Payload.ArrayFiller,
374 .pub_inline_fn => Payload.PubInlineFn,364 .pub_inline_fn => Payload.PubInlineFn,
375 .field_access => Payload.FieldAccess,365 .field_access => Payload.FieldAccess,
...@@ -554,19 +544,6 @@ pub const Payload = struct {...@@ -554,19 +544,6 @@ pub const Payload = struct {
554 type: Node,544 type: Node,
555 };545 };
556546
557 pub const Enum = struct {
558 base: Payload,
559 data: struct {
560 int_type: Node,
561 fields: []Field,
562 },
563
564 pub const Field = struct {
565 name: []const u8,
566 value: ?Node,
567 };
568 };
569
570 pub const Record = struct {547 pub const Record = struct {
571 base: Payload,548 base: Payload,
572 data: struct {549 data: struct {
...@@ -658,12 +635,13 @@ pub const Payload = struct {...@@ -658,12 +635,13 @@ pub const Payload = struct {
658 },635 },
659 };636 };
660637
661 pub const EnumRedecl = struct {638 pub const EnumConstant = struct {
662 base: Payload,639 base: Payload,
663 data: struct {640 data: struct {
664 enum_val_name: []const u8,641 name: []const u8,
665 field_name: []const u8,642 is_public: bool,
666 enum_name: []const u8,643 type: ?Node,
644 value: Node,
667 },645 },
668 };646 };
669647
...@@ -1307,14 +1285,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1307,14 +1285,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1307 const payload = node.castTag(.int_to_float).?.data;1285 const payload = node.castTag(.int_to_float).?.data;
1308 return renderBuiltinCall(c, "@intToFloat", &.{ payload.lhs, payload.rhs });1286 return renderBuiltinCall(c, "@intToFloat", &.{ payload.lhs, payload.rhs });
1309 },1287 },
1310 .int_to_enum => {
1311 const payload = node.castTag(.int_to_enum).?.data;
1312 return renderBuiltinCall(c, "@intToEnum", &.{ payload.lhs, payload.rhs });
1313 },
1314 .enum_to_int => {
1315 const payload = node.castTag(.enum_to_int).?.data;
1316 return renderBuiltinCall(c, "@enumToInt", &.{payload});
1317 },
1318 .int_to_ptr => {1288 .int_to_ptr => {
1319 const payload = node.castTag(.int_to_ptr).?.data;1289 const payload = node.castTag(.int_to_ptr).?.data;
1320 return renderBuiltinCall(c, "@intToPtr", &.{ payload.lhs, payload.rhs });1290 return renderBuiltinCall(c, "@intToPtr", &.{ payload.lhs, payload.rhs });
...@@ -1814,91 +1784,28 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {...@@ -1814,91 +1784,28 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex {
1814 return renderFieldAccess(c, lhs, payload.field_name);1784 return renderFieldAccess(c, lhs, payload.field_name);
1815 },1785 },
1816 .@"struct", .@"union" => return renderRecord(c, node),1786 .@"struct", .@"union" => return renderRecord(c, node),
1817 .@"enum" => {1787 .enum_constant => {
1818 const payload = node.castTag(.@"enum").?.data;1788 const payload = node.castTag(.enum_constant).?.data;
1819 _ = try c.addToken(.keyword_extern, "extern");
1820 const enum_tok = try c.addToken(.keyword_enum, "enum");
1821 _ = try c.addToken(.l_paren, "(");
1822 const arg_expr = try renderNode(c, payload.int_type);
1823 _ = try c.addToken(.r_paren, ")");
1824 _ = try c.addToken(.l_brace, "{");
1825 const members = try c.gpa.alloc(NodeIndex, payload.fields.len + 1);
1826 defer c.gpa.free(members);
1827 members[0] = 0;
1828
1829 for (payload.fields) |field, i| {
1830 const name_tok = try c.addIdentifier(field.name);
1831 const value_expr = if (field.value) |some| blk: {
1832 _ = try c.addToken(.equal, "=");
1833 break :blk try renderNode(c, some);
1834 } else 0;
1835
1836 members[i] = try c.addNode(.{
1837 .tag = .container_field_init,
1838 .main_token = name_tok,
1839 .data = .{
1840 .lhs = 0,
1841 .rhs = value_expr,
1842 },
1843 });
1844 _ = try c.addToken(.comma, ",");
1845 }
1846 // make non-exhaustive
1847 members[payload.fields.len] = try c.addNode(.{
1848 .tag = .container_field_init,
1849 .main_token = try c.addIdentifier("_"),
1850 .data = .{
1851 .lhs = 0,
1852 .rhs = 0,
1853 },
1854 });
1855 _ = try c.addToken(.comma, ",");
1856 _ = try c.addToken(.r_brace, "}");
18571789
1858 const span = try c.listToSpan(members);1790 if (payload.is_public) _ = try c.addToken(.keyword_pub, "pub");
1859 return c.addNode(.{
1860 .tag = .container_decl_arg_trailing,
1861 .main_token = enum_tok,
1862 .data = .{
1863 .lhs = arg_expr,
1864 .rhs = try c.addExtra(NodeSubRange{
1865 .start = span.start,
1866 .end = span.end,
1867 }),
1868 },
1869 });
1870 },
1871 .pub_enum_redecl, .enum_redecl => {
1872 const payload = @fieldParentPtr(Payload.EnumRedecl, "base", node.ptr_otherwise).data;
1873 if (node.tag() == .pub_enum_redecl) _ = try c.addToken(.keyword_pub, "pub");
1874 const const_tok = try c.addToken(.keyword_const, "const");1791 const const_tok = try c.addToken(.keyword_const, "const");
1875 _ = try c.addIdentifier(payload.enum_val_name);1792 _ = try c.addIdentifier(payload.name);
1793
1794 const type_node = if (payload.type) |enum_const_type| blk: {
1795 _ = try c.addToken(.colon, ":");
1796 break :blk try renderNode(c, enum_const_type);
1797 } else 0;
1798
1876 _ = try c.addToken(.equal, "=");1799 _ = try c.addToken(.equal, "=");
18771800
1878 const enum_to_int_tok = try c.addToken(.builtin, "@enumToInt");1801 const init_node = try renderNode(c, payload.value);
1879 _ = try c.addToken(.l_paren, "(");
1880 const enum_name = try c.addNode(.{
1881 .tag = .identifier,
1882 .main_token = try c.addIdentifier(payload.enum_name),
1883 .data = undefined,
1884 });
1885 const field_access = try renderFieldAccess(c, enum_name, payload.field_name);
1886 const init_node = try c.addNode(.{
1887 .tag = .builtin_call_two,
1888 .main_token = enum_to_int_tok,
1889 .data = .{
1890 .lhs = field_access,
1891 .rhs = 0,
1892 },
1893 });
1894 _ = try c.addToken(.r_paren, ")");
1895 _ = try c.addToken(.semicolon, ";");1802 _ = try c.addToken(.semicolon, ";");
18961803
1897 return c.addNode(.{1804 return c.addNode(.{
1898 .tag = .simple_var_decl,1805 .tag = .simple_var_decl,
1899 .main_token = const_tok,1806 .main_token = const_tok,
1900 .data = .{1807 .data = .{
1901 .lhs = 0,1808 .lhs = type_node,
1902 .rhs = init_node,1809 .rhs = init_node,
1903 },1810 },
1904 });1811 });
...@@ -2210,7 +2117,7 @@ fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIn...@@ -2210,7 +2117,7 @@ fn renderNullSentinelArrayType(c: *Context, len: usize, elem_type: Node) !NodeIn
2210fn addSemicolonIfNeeded(c: *Context, node: Node) !void {2117fn addSemicolonIfNeeded(c: *Context, node: Node) !void {
2211 switch (node.tag()) {2118 switch (node.tag()) {
2212 .warning => unreachable,2119 .warning => unreachable,
2213 .var_decl, .var_simple, .arg_redecl, .alias, .enum_redecl, .block, .empty_block, .block_single, .@"switch" => {},2120 .var_decl, .var_simple, .arg_redecl, .alias, .block, .empty_block, .block_single, .@"switch" => {},
2214 .while_true => {2121 .while_true => {
2215 const payload = node.castTag(.while_true).?.data;2122 const payload = node.castTag(.while_true).?.data;
2216 return addSemicolonIfNotBlock(c, payload);2123 return addSemicolonIfNotBlock(c, payload);
...@@ -2258,13 +2165,11 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -2258,13 +2165,11 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
2258 .float_cast,2165 .float_cast,
2259 .float_to_int,2166 .float_to_int,
2260 .int_to_float,2167 .int_to_float,
2261 .int_to_enum,
2262 .int_to_ptr,2168 .int_to_ptr,
2263 .std_mem_zeroes,2169 .std_mem_zeroes,
2264 .std_math_Log2Int,2170 .std_math_Log2Int,
2265 .log2_int_type,2171 .log2_int_type,
2266 .ptr_to_int,2172 .ptr_to_int,
2267 .enum_to_int,
2268 .sizeof,2173 .sizeof,
2269 .alignof,2174 .alignof,
2270 .typeof,2175 .typeof,
...@@ -2340,7 +2245,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -2340,7 +2245,6 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
2340 .array_cat,2245 .array_cat,
2341 .array_filler,2246 .array_filler,
2342 .@"if",2247 .@"if",
2343 .@"enum",
2344 .@"struct",2248 .@"struct",
2345 .@"union",2249 .@"union",
2346 .array_init,2250 .array_init,
...@@ -2366,8 +2270,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {...@@ -2366,8 +2270,7 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex {
2366 .alias,2270 .alias,
2367 .var_simple,2271 .var_simple,
2368 .pub_var_simple,2272 .pub_var_simple,
2369 .pub_enum_redecl,2273 .enum_constant,
2370 .enum_redecl,
2371 .@"while",2274 .@"while",
2372 .@"switch",2275 .@"switch",
2373 .@"break",2276 .@"break",
src/zig_clang.cpp-6
...@@ -3228,12 +3228,6 @@ bool ZigClangEnumDecl_enumerator_iterator_neq(...@@ -3228,12 +3228,6 @@ bool ZigClangEnumDecl_enumerator_iterator_neq(
3228 return casted_a != casted_b;3228 return casted_a != casted_b;
3229}3229}
32303230
3231const struct ZigClangExpr *ZigClangEnumConstantDecl_getInitExpr(const struct ZigClangEnumConstantDecl *self) {
3232 auto casted = reinterpret_cast<const clang::EnumConstantDecl *>(self);
3233 const clang::Expr *result = casted->getInitExpr();
3234 return reinterpret_cast<const ZigClangExpr *>(result);
3235}
3236
3237const struct ZigClangAPSInt *ZigClangEnumConstantDecl_getInitVal(const struct ZigClangEnumConstantDecl *self) {3231const struct ZigClangAPSInt *ZigClangEnumConstantDecl_getInitVal(const struct ZigClangEnumConstantDecl *self) {
3238 auto casted = reinterpret_cast<const clang::EnumConstantDecl *>(self);3232 auto casted = reinterpret_cast<const clang::EnumConstantDecl *>(self);
3239 const llvm::APSInt *result = &casted->getInitVal();3233 const llvm::APSInt *result = &casted->getInitVal();
src/zig_clang.h-1
...@@ -1326,6 +1326,5 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFieldDecl_getLocation(const s...@@ -1326,6 +1326,5 @@ ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangFieldDecl_getLocation(const s
1326ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangFieldDecl_getParent(const struct ZigClangFieldDecl *);1326ZIG_EXTERN_C const struct ZigClangRecordDecl *ZigClangFieldDecl_getParent(const struct ZigClangFieldDecl *);
1327ZIG_EXTERN_C unsigned ZigClangFieldDecl_getFieldIndex(const struct ZigClangFieldDecl *);1327ZIG_EXTERN_C unsigned ZigClangFieldDecl_getFieldIndex(const struct ZigClangFieldDecl *);
13281328
1329ZIG_EXTERN_C const struct ZigClangExpr *ZigClangEnumConstantDecl_getInitExpr(const struct ZigClangEnumConstantDecl *);
1330ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangEnumConstantDecl_getInitVal(const struct ZigClangEnumConstantDecl *);1329ZIG_EXTERN_C const struct ZigClangAPSInt *ZigClangEnumConstantDecl_getInitVal(const struct ZigClangEnumConstantDecl *);
1331#endif1330#endif
test/run_translated_c.zig+49
...@@ -1598,4 +1598,53 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {...@@ -1598,4 +1598,53 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
1598 \\ return 0;1598 \\ return 0;
1599 \\}1599 \\}
1600 , "");1600 , "");
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 , "");
1617
1618 cases.add("Enum constant matches enum name; multiple enumerations with same value",
1619 \\#include <stdlib.h>
1620 \\enum FOO {
1621 \\ FOO = 1,
1622 \\ BAR = 2,
1623 \\ BAZ = 1,
1624 \\};
1625 \\int main(void) {
1626 \\ enum FOO x = BAZ;
1627 \\ if (x != 1) abort();
1628 \\ if (x != BAZ) abort();
1629 \\ if (x != FOO) abort();
1630 \\}
1631 , "");
1632
1633 cases.add("Scoped enums",
1634 \\#include <stdlib.h>
1635 \\int main(void) {
1636 \\ enum Foo { A, B, C };
1637 \\ enum Foo a = B;
1638 \\ if (a != B) abort();
1639 \\ if (a != 1) abort();
1640 \\ {
1641 \\ enum Foo { A = 5, B = 6, C = 7 };
1642 \\ enum Foo a = B;
1643 \\ if (a != B) abort();
1644 \\ if (a != 6) abort();
1645 \\ }
1646 \\ if (a != B) abort();
1647 \\ if (a != 1) abort();
1648 \\}
1649 , "");
1601}1650}
test/translate_c.zig+90-191
...@@ -30,15 +30,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -30,15 +30,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
30 \\ int a, b;30 \\ int a, b;
31 \\} Bar;31 \\} Bar;
32 , &[_][]const u8{32 , &[_][]const u8{
33 \\pub const Foo = extern enum(33 \\pub const FooA: c_int = 0;
34 ++ default_enum_type ++34 \\pub const FooB: c_int = 1;
35 \\) {35 \\pub const Foo =
36 \\ A,36 ++ " " ++ default_enum_type ++
37 \\ B,37 \\;
38 \\ _,
39 \\};
40 \\pub const FooA = @enumToInt(Foo.A);
41 \\pub const FooB = @enumToInt(Foo.B);
42 \\pub const Bar = extern struct {38 \\pub const Bar = extern struct {
43 \\ a: c_int,39 \\ a: c_int,
44 \\ b: c_int,40 \\ b: c_int,
...@@ -103,54 +99,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -103,54 +99,6 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
103 \\pub const PTR = ?*c_void;99 \\pub const PTR = ?*c_void;
104 });100 });
105101
106 cases.add("scoped enum",
107 \\void foo() {
108 \\ enum Foo {
109 \\ A,
110 \\ B,
111 \\ C,
112 \\ };
113 \\ enum Foo a = B;
114 \\ {
115 \\ enum Foo {
116 \\ A,
117 \\ B,
118 \\ C,
119 \\ };
120 \\ enum Foo a = B;
121 \\ }
122 \\}
123 , &[_][]const u8{
124 \\pub export fn foo() void {
125 \\ const enum_Foo = extern enum(
126 ++ default_enum_type ++
127 \\) {
128 \\ A,
129 \\ B,
130 \\ C,
131 \\ _,
132 \\ };
133 \\ const A = @enumToInt(enum_Foo.A);
134 \\ const B = @enumToInt(enum_Foo.B);
135 \\ const C = @enumToInt(enum_Foo.C);
136 \\ var a: enum_Foo = @import("std").zig.c_translation.cast(enum_Foo, B);
137 \\ {
138 \\ const enum_Foo = extern enum(
139 ++ default_enum_type ++
140 \\) {
141 \\ A,
142 \\ B,
143 \\ C,
144 \\ _,
145 \\ };
146 \\ const A_2 = @enumToInt(enum_Foo.A);
147 \\ const B_3 = @enumToInt(enum_Foo.B);
148 \\ const C_4 = @enumToInt(enum_Foo.C);
149 \\ var a_5: enum_Foo = @import("std").zig.c_translation.cast(enum_Foo, B_3);
150 \\ }
151 \\}
152 });
153
154 cases.add("scoped record",102 cases.add("scoped record",
155 \\void foo() {103 \\void foo() {
156 \\ struct Foo {104 \\ struct Foo {
...@@ -1208,32 +1156,30 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1208,32 +1156,30 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1208 \\ VAL23 = 0xFFFFFFFFFFFFFFFF,1156 \\ VAL23 = 0xFFFFFFFFFFFFFFFF,
1209 \\};1157 \\};
1210 , &[_][]const u8{1158 , &[_][]const u8{
1211 \\pub const enum_EnumWithInits = extern enum(c_longlong) {1159 \\pub const VAL01: c_int = 0;
1212 \\ VAL01 = 0,1160 \\pub const VAL02: c_int = 1;
1213 \\ VAL02 = 1,1161 \\pub const VAL03: c_int = 2;
1214 \\ VAL03 = 2,1162 \\pub const VAL04: c_int = 3;
1215 \\ VAL04 = 3,1163 \\pub const VAL05: c_int = -1;
1216 \\ VAL05 = -1,1164 \\pub const VAL06: c_int = -2;
1217 \\ VAL06 = -2,1165 \\pub const VAL07: c_int = -3;
1218 \\ VAL07 = -3,1166 \\pub const VAL08: c_int = -4;
1219 \\ VAL08 = -4,1167 \\pub const VAL09: c_int = -3;
1220 \\ VAL09 = -3,1168 \\pub const VAL10: c_int = -1000012000;
1221 \\ VAL10 = -1000012000,1169 \\pub const VAL11: c_int = -1000161000;
1222 \\ VAL11 = -1000161000,1170 \\pub const VAL12: c_int = -1000174001;
1223 \\ VAL12 = -1000174001,1171 \\pub const VAL13: c_int = -3;
1224 \\ VAL13 = -3,1172 \\pub const VAL14: c_int = -1000012000;
1225 \\ VAL14 = -1000012000,1173 \\pub const VAL15: c_int = -1000161000;
1226 \\ VAL15 = -1000161000,1174 \\pub const VAL16: c_int = -3;
1227 \\ VAL16 = -3,1175 \\pub const VAL17: c_int = 1000011998;
1228 \\ VAL17 = 1000011998,1176 \\pub const VAL18: c_longlong = 1152921504606846976;
1229 \\ VAL18 = 1152921504606846976,1177 \\pub const VAL19: c_longlong = 3458764513820540927;
1230 \\ VAL19 = 3458764513820540927,1178 \\pub const VAL20: c_longlong = 6917529027641081854;
1231 \\ VAL20 = 6917529027641081854,1179 \\pub const VAL21: c_longlong = 6917529027641081853;
1232 \\ VAL21 = 6917529027641081853,1180 \\pub const VAL22: c_int = 0;
1233 \\ VAL22 = 0,1181 \\pub const VAL23: c_longlong = -1;
1234 \\ VAL23 = -1,1182 \\pub const enum_EnumWithInits = c_longlong;
1235 \\ _,
1236 \\};
1237 });1183 });
1238 }1184 }
12391185
...@@ -1591,11 +1537,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1591,11 +1537,8 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1591 \\extern enum enum_ty my_enum;1537 \\extern enum enum_ty my_enum;
1592 \\enum enum_ty { FOO };1538 \\enum enum_ty { FOO };
1593 , &[_][]const u8{1539 , &[_][]const u8{
1594 \\pub const enum_enum_ty = extern enum(c_int) {1540 \\pub const FOO: c_int = 0;
1595 \\ FOO,1541 \\pub const enum_enum_ty = c_int;
1596 \\ _,
1597 \\};
1598 \\pub const FOO = @enumToInt(enum_enum_ty.FOO);
1599 \\pub extern var my_enum: enum_enum_ty;1542 \\pub extern var my_enum: enum_enum_ty;
1600 });1543 });
16011544
...@@ -1716,57 +1659,37 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1716,57 +1659,37 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1716 \\ p,1659 \\ p,
1717 \\};1660 \\};
1718 , &[_][]const u8{1661 , &[_][]const u8{
1719 \\pub const d = extern enum(1662 \\pub const a: c_int = 0;
1720 ++ default_enum_type ++1663 \\pub const b: c_int = 1;
1721 \\) {1664 \\pub const c: c_int = 2;
1722 \\ a,1665 \\pub const d =
1723 \\ b,1666 ++ " " ++ default_enum_type ++
1724 \\ c,1667 \\;
1725 \\ _,1668 \\pub const e: c_int = 0;
1726 \\};1669 \\pub const f: c_int = 4;
1727 \\pub const a = @enumToInt(d.a);1670 \\pub const g: c_int = 5;
1728 \\pub const b = @enumToInt(d.b);1671 \\const enum_unnamed_1 =
1729 \\pub const c = @enumToInt(d.c);1672 ++ " " ++ default_enum_type ++
1730 \\const enum_unnamed_1 = extern enum(1673 \\;
1731 ++ default_enum_type ++1674 \\pub export var h: enum_unnamed_1 = @bitCast(c_uint, e);
1732 \\) {1675 \\pub const i: c_int = 0;
1733 \\ e = 0,1676 \\pub const j: c_int = 1;
1734 \\ f = 4,1677 \\pub const k: c_int = 2;
1735 \\ g = 5,1678 \\const enum_unnamed_2 =
1736 \\ _,1679 ++ " " ++ default_enum_type ++
1737 \\};1680 \\;
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);
1741 \\pub export var h: enum_unnamed_1 = @import("std").zig.c_translation.cast(enum_unnamed_1, e);
1742 \\const enum_unnamed_2 = extern enum(
1743 ++ default_enum_type ++
1744 \\) {
1745 \\ i,
1746 \\ j,
1747 \\ k,
1748 \\ _,
1749 \\};
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);
1753 \\pub const struct_Baz = extern struct {1681 \\pub const struct_Baz = extern struct {
1754 \\ l: enum_unnamed_2,1682 \\ l: enum_unnamed_2,
1755 \\ m: d,1683 \\ m: d,
1756 \\};1684 \\};
1757 \\pub const enum_i = extern enum(1685 \\pub const n: c_int = 0;
1758 ++ default_enum_type ++1686 \\pub const o: c_int = 1;
1759 \\) {1687 \\pub const p: c_int = 2;
1760 \\ n,1688 \\pub const enum_i =
1761 \\ o,1689 ++ " " ++ default_enum_type ++
1762 \\ p,1690 \\;
1763 \\ _,
1764 \\};
1765 \\pub const n = @enumToInt(enum_i.n);
1766 \\pub const o = @enumToInt(enum_i.o);
1767 \\pub const p = @enumToInt(enum_i.p);
1768 ,1691 ,
1769 \\pub const Baz = struct_Baz;1692 "pub const Baz = struct_Baz;",
1770 });1693 });
17711694
1772 cases.add("#define a char literal",1695 cases.add("#define a char literal",
...@@ -2257,15 +2180,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2257,15 +2180,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2257 \\ Two,2180 \\ Two,
2258 \\};2181 \\};
2259 , &[_][]const u8{2182 , &[_][]const u8{
2260 \\const enum_unnamed_1 = extern enum(2183 \\pub const One: c_int = 0;
2261 ++ default_enum_type ++2184 \\pub const Two: c_int = 1;
2262 \\) {2185 \\const enum_unnamed_1 =
2263 \\ One,2186 ++ " " ++ default_enum_type ++
2264 \\ Two,2187 \\;
2265 \\ _,
2266 \\};
2267 \\pub const One = @enumToInt(enum_unnamed_1.One);
2268 \\pub const Two = @enumToInt(enum_unnamed_1.Two);
2269 });2188 });
22702189
2271 cases.add("c style cast",2190 cases.add("c style cast",
...@@ -2363,32 +2282,27 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2363,32 +2282,27 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2363 \\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);2282 \\ return ((((((((((e + f) + g) + h) + i) + j) + k) + l) + m) + o) + p);
2364 \\}2283 \\}
2365 , &[_][]const u8{2284 , &[_][]const u8{
2366 \\pub const enum_Foo = extern enum(2285 \\pub const FooA: c_int = 0;
2367 ++ default_enum_type ++2286 \\pub const FooB: c_int = 1;
2368 \\) {2287 \\pub const FooC: c_int = 2;
2369 \\ A,2288 \\pub const enum_Foo =
2370 \\ B,2289 ++ " " ++ default_enum_type ++
2371 \\ C,2290 \\;
2372 \\ _,
2373 \\};
2374 \\pub const FooA = @enumToInt(enum_Foo.A);
2375 \\pub const FooB = @enumToInt(enum_Foo.B);
2376 \\pub const FooC = @enumToInt(enum_Foo.C);
2377 \\pub const SomeTypedef = c_int;2291 \\pub const SomeTypedef = c_int;
2378 \\pub export fn and_or_non_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void) c_int {2292 \\pub export fn and_or_non_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void) c_int {
2379 \\ var a = arg_a;2293 \\ var a = arg_a;
2380 \\ var b = arg_b;2294 \\ var b = arg_b;
2381 \\ var c = arg_c;2295 \\ var c = arg_c;
2382 \\ var d: enum_Foo = @import("std").zig.c_translation.cast(enum_Foo, FooA);2296 \\ var d: enum_Foo = @bitCast(c_uint, FooA);
2383 \\ var e: c_int = @boolToInt((a != 0) and (b != 0));2297 \\ var e: c_int = @boolToInt((a != 0) and (b != 0));
2384 \\ var f: c_int = @boolToInt((b != 0) and (c != null));2298 \\ var f: c_int = @boolToInt((b != 0) and (c != null));
2385 \\ var g: c_int = @boolToInt((a != 0) and (c != null));2299 \\ var g: c_int = @boolToInt((a != 0) and (c != null));
2386 \\ var h: c_int = @boolToInt((a != 0) or (b != 0));2300 \\ var h: c_int = @boolToInt((a != 0) or (b != 0));
2387 \\ var i: c_int = @boolToInt((b != 0) or (c != null));2301 \\ var i: c_int = @boolToInt((b != 0) or (c != null));
2388 \\ var j: c_int = @boolToInt((a != 0) or (c != null));2302 \\ var j: c_int = @boolToInt((a != 0) or (c != null));
2389 \\ var k: c_int = @boolToInt((a != 0) or (@bitCast(c_int, @enumToInt(d)) != 0));2303 \\ var k: c_int = @boolToInt((a != 0) or (@bitCast(c_int, d) != 0));
2390 \\ var l: c_int = @boolToInt((@bitCast(c_int, @enumToInt(d)) != 0) and (b != 0));2304 \\ var l: c_int = @boolToInt((@bitCast(c_int, d) != 0) and (b != 0));
2391 \\ var m: c_int = @boolToInt((c != null) or (@bitCast(c_uint, @enumToInt(d)) != 0));2305 \\ var m: c_int = @boolToInt((c != null) or (d != 0));
2392 \\ var td: SomeTypedef = 44;2306 \\ var td: SomeTypedef = 44;
2393 \\ var o: c_int = @boolToInt((td != 0) or (b != 0));2307 \\ var o: c_int = @boolToInt((td != 0) or (b != 0));
2394 \\ var p: c_int = @boolToInt((c != null) and (td != 0));2308 \\ var p: c_int = @boolToInt((c != null) and (td != 0));
...@@ -2413,16 +2327,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2413,16 +2327,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2413 \\ x: c_int,2327 \\ x: c_int,
2414 \\ y: c_int,2328 \\ y: c_int,
2415 \\};2329 \\};
2416 ,2330 \\pub const BarA: c_int = 0;
2417 \\pub const enum_Bar = extern enum(2331 \\pub const BarB: c_int = 1;
2418 ++ default_enum_type ++2332 \\pub const enum_Bar =
2419 \\) {2333 ++ " " ++ default_enum_type ++
2420 \\ A,2334 \\;
2421 \\ B,
2422 \\ _,
2423 \\};
2424 \\pub const BarA = @enumToInt(enum_Bar.A);
2425 \\pub const BarB = @enumToInt(enum_Bar.B);
2426 \\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void;2335 \\pub extern fn func(a: [*c]struct_Foo, b: [*c][*c]enum_Bar) void;
2427 ,2336 ,
2428 \\pub const Foo = struct_Foo;2337 \\pub const Foo = struct_Foo;
...@@ -2693,17 +2602,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2693,17 +2602,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2693 \\ return 4;2602 \\ return 4;
2694 \\}2603 \\}
2695 , &[_][]const u8{2604 , &[_][]const u8{
2696 \\pub const enum_SomeEnum = extern enum(2605 \\pub const A: c_int = 0;
2697 ++ default_enum_type ++2606 \\pub const B: c_int = 1;
2698 \\) {2607 \\pub const C: c_int = 2;
2699 \\ A,2608 \\pub const enum_SomeEnum =
2700 \\ B,2609 ++ " " ++ default_enum_type ++
2701 \\ C,2610 \\;
2702 \\ _,
2703 \\};
2704 \\pub const A = @enumToInt(enum_SomeEnum.A);
2705 \\pub const B = @enumToInt(enum_SomeEnum.B);
2706 \\pub const C = @enumToInt(enum_SomeEnum.C);
2707 \\pub export fn if_none_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void, arg_d: enum_SomeEnum) c_int {2611 \\pub export fn if_none_bool(arg_a: c_int, arg_b: f32, arg_c: ?*c_void, arg_d: enum_SomeEnum) c_int {
2708 \\ var a = arg_a;2612 \\ var a = arg_a;
2709 \\ var b = arg_b;2613 \\ var b = arg_b;
...@@ -2712,7 +2616,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2712,7 +2616,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2712 \\ if (a != 0) return 0;2616 \\ if (a != 0) return 0;
2713 \\ if (b != 0) return 1;2617 \\ if (b != 0) return 1;
2714 \\ if (c != null) return 2;2618 \\ if (c != null) return 2;
2715 \\ if (@enumToInt(d) != 0) return 3;2619 \\ if (d != 0) return 3;
2716 \\ return 4;2620 \\ return 4;
2717 \\}2621 \\}
2718 });2622 });
...@@ -3161,17 +3065,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -3161,17 +3065,12 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
3161 \\ Foo1,3065 \\ Foo1,
3162 \\};3066 \\};
3163 , &[_][]const u8{3067 , &[_][]const u8{
3164 \\pub const enum_Foo = extern enum(3068 \\pub const FooA: c_int = 2;
3165 ++ default_enum_type ++3069 \\pub const FooB: c_int = 5;
3166 \\) {3070 \\pub const Foo1: c_int = 6;
3167 \\ A = 2,3071 \\pub const enum_Foo =
3168 \\ B = 5,3072 ++ " " ++ default_enum_type ++
3169 \\ @"1" = 6,3073 \\;
3170 \\ _,
3171 \\};
3172 \\pub const FooA = @enumToInt(enum_Foo.A);
3173 \\pub const FooB = @enumToInt(enum_Foo.B);
3174 \\pub const Foo1 = @enumToInt(enum_Foo.@"1");
3175 ,3074 ,
3176 \\pub const Foo = enum_Foo;3075 \\pub const Foo = enum_Foo;
3177 });3076 });