diff --git a/src/translate_c.zig b/src/translate_c.zig index 8d5804c5e5..4078bd0f34 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -1010,17 +1010,23 @@ fn buildFlexibleArrayFn( const bit_offset = layout.getFieldOffset(field_index); // this is a target-specific constant based on the struct layout const byte_offset = bit_offset / 8; - const casted_self = try Tag.ptr_cast.create(c.arena, .{ + const casted_self = try Tag.as.create(c.arena, .{ .lhs = intermediate_type_ident, - .rhs = self_param, + .rhs = try Tag.ptr_cast.create(c.arena, self_param), }); const field_offset = try transCreateNodeNumber(c, byte_offset, .int); const field_ptr = try Tag.add.create(c.arena, .{ .lhs = casted_self, .rhs = field_offset }); - const alignment = try Tag.alignof.create(c.arena, element_type); - - const ptr_val = try Tag.align_cast.create(c.arena, .{ .lhs = alignment, .rhs = field_ptr }); - const ptr_cast = try Tag.ptr_cast.create(c.arena, .{ .lhs = return_type_ident, .rhs = ptr_val }); + const ptr_cast = try Tag.as.create(c.arena, .{ + .lhs = return_type_ident, + .rhs = try Tag.ptr_cast.create( + c.arena, + try Tag.align_cast.create( + c.arena, + field_ptr, + ), + ), + }); const return_stmt = try Tag.@"return".create(c.arena, ptr_cast); try block_scope.statements.append(return_stmt); @@ -1579,14 +1585,14 @@ fn transOffsetOfExpr( /// pointer arithmetic expressions, where wraparound will ensure we get the correct value. /// node -> @bitCast(usize, @intCast(isize, node)) fn usizeCastForWrappingPtrArithmetic(gpa: mem.Allocator, node: Node) TransError!Node { - const intcast_node = try Tag.int_cast.create(gpa, .{ + const intcast_node = try Tag.as.create(gpa, .{ .lhs = try Tag.type.create(gpa, "isize"), - .rhs = node, + .rhs = try Tag.int_cast.create(gpa, node), }); - return Tag.bit_cast.create(gpa, .{ + return Tag.as.create(gpa, .{ .lhs = try Tag.type.create(gpa, "usize"), - .rhs = intcast_node, + .rhs = try Tag.bit_cast.create(gpa, intcast_node), }); } @@ -1781,7 +1787,10 @@ fn transBinaryOperator( const elem_type = c_pointer.castTag(.c_pointer).?.data.elem_type; const sizeof = try Tag.sizeof.create(c.arena, elem_type); - const bitcast = try Tag.bit_cast.create(c.arena, .{ .lhs = ptrdiff_type, .rhs = infixOpNode }); + const bitcast = try Tag.as.create(c.arena, .{ + .lhs = ptrdiff_type, + .rhs = try Tag.bit_cast.create(c.arena, infixOpNode), + }); return Tag.div_exact.create(c.arena, .{ .lhs = bitcast, @@ -2310,7 +2319,7 @@ fn transIntegerLiteral( // unsigned char y = 256; // How this gets evaluated is the 256 is an integer, which gets truncated to signed char, then bit-casted // to unsigned char, resulting in 0. In order for this to work, we have to emit this zig code: - // var y = @bitCast(u8, @truncate(i8, @as(c_int, 256))); + // var y = @as(u8, @bitCast(@as(i8, @truncate(@as(c_int, 256))))); // Ideally in translate-c we could flatten this out to simply: // var y: u8 = 0; // But the first step is to be correct, and the next step is to make the output more elegant. @@ -2501,7 +2510,10 @@ fn transCCast( .lt => { // @truncate(SameSignSmallerInt, src_int_expr) const ty_node = try transQualTypeIntWidthOf(c, dst_type, src_type_is_signed); - src_int_expr = try Tag.truncate.create(c.arena, .{ .lhs = ty_node, .rhs = src_int_expr }); + src_int_expr = try Tag.as.create(c.arena, .{ + .lhs = ty_node, + .rhs = try Tag.truncate.create(c.arena, src_int_expr), + }); }, .gt => { // @as(SameSignBiggerInt, src_int_expr) @@ -2512,36 +2524,57 @@ fn transCCast( // src_int_expr = src_int_expr }, } - // @bitCast(dest_type, intermediate_value) - return Tag.bit_cast.create(c.arena, .{ .lhs = dst_node, .rhs = src_int_expr }); + // @as(dest_type, @bitCast(intermediate_value)) + return Tag.as.create(c.arena, .{ + .lhs = dst_node, + .rhs = try Tag.bit_cast.create(c.arena, src_int_expr), + }); } if (cIsVector(src_type) or cIsVector(dst_type)) { // C cast where at least 1 operand is a vector requires them to be same size - // @bitCast(dest_type, val) - return Tag.bit_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); + // @as(dest_type, @bitCast(val)) + return Tag.as.create(c.arena, .{ + .lhs = dst_node, + .rhs = try Tag.bit_cast.create(c.arena, expr), + }); } if (cIsInteger(dst_type) and qualTypeIsPtr(src_type)) { // @intCast(dest_type, @intFromPtr(val)) const int_from_ptr = try Tag.int_from_ptr.create(c.arena, expr); - return Tag.int_cast.create(c.arena, .{ .lhs = dst_node, .rhs = int_from_ptr }); + return Tag.as.create(c.arena, .{ + .lhs = dst_node, + .rhs = try Tag.int_cast.create(c.arena, int_from_ptr), + }); } if (cIsInteger(src_type) and qualTypeIsPtr(dst_type)) { - // @ptrFromInt(dest_type, val) - return Tag.ptr_from_int.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); + // @as(dest_type, @ptrFromInt(val)) + return Tag.as.create(c.arena, .{ + .lhs = dst_node, + .rhs = try Tag.ptr_from_int.create(c.arena, expr), + }); } if (cIsFloating(src_type) and cIsFloating(dst_type)) { - // @floatCast(dest_type, val) - return Tag.float_cast.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); + // @as(dest_type, @floatCast(val)) + return Tag.as.create(c.arena, .{ + .lhs = dst_node, + .rhs = try Tag.float_cast.create(c.arena, expr), + }); } if (cIsFloating(src_type) and !cIsFloating(dst_type)) { - // @intFromFloat(dest_type, val) - return Tag.int_from_float.create(c.arena, .{ .lhs = dst_node, .rhs = expr }); + // @as(dest_type, @intFromFloat(val)) + return Tag.as.create(c.arena, .{ + .lhs = dst_node, + .rhs = try Tag.int_from_float.create(c.arena, expr), + }); } if (!cIsFloating(src_type) and cIsFloating(dst_type)) { var rhs = expr; if (qualTypeIsBoolean(src_type)) rhs = try Tag.int_from_bool.create(c.arena, expr); - // @floatFromInt(dest_type, val) - return Tag.float_from_int.create(c.arena, .{ .lhs = dst_node, .rhs = rhs }); + // @as(dest_type, @floatFromInt(val)) + return Tag.as.create(c.arena, .{ + .lhs = dst_node, + .rhs = try Tag.float_from_int.create(c.arena, rhs), + }); } if (qualTypeIsBoolean(src_type) and !qualTypeIsBoolean(dst_type)) { // @intFromBool returns a u1 @@ -3487,9 +3520,9 @@ fn transSignedArrayAccess( const then_value = try Tag.add.create(c.arena, .{ .lhs = container_node, - .rhs = try Tag.int_cast.create(c.arena, .{ + .rhs = try Tag.as.create(c.arena, .{ .lhs = try Tag.type.create(c.arena, "usize"), - .rhs = tmp_ref, + .rhs = try Tag.int_cast.create(c.arena, tmp_ref), }), }); @@ -3499,17 +3532,17 @@ fn transSignedArrayAccess( }); const minuend = container_node; - const signed_size = try Tag.int_cast.create(c.arena, .{ + const signed_size = try Tag.as.create(c.arena, .{ .lhs = try Tag.type.create(c.arena, "isize"), - .rhs = tmp_ref, + .rhs = try Tag.int_cast.create(c.arena, tmp_ref), }); const to_cast = try Tag.add_wrap.create(c.arena, .{ .lhs = signed_size, .rhs = try Tag.negate.create(c.arena, Tag.one_literal.init()), }); - const bitcast_node = try Tag.bit_cast.create(c.arena, .{ + const bitcast_node = try Tag.as.create(c.arena, .{ .lhs = try Tag.type.create(c.arena, "usize"), - .rhs = to_cast, + .rhs = try Tag.bit_cast.create(c.arena, to_cast), }); const subtrahend = try Tag.bit_not.create(c.arena, bitcast_node); const difference = try Tag.sub.create(c.arena, .{ @@ -3566,7 +3599,13 @@ fn transArrayAccess(c: *Context, scope: *Scope, stmt: *const clang.ArraySubscrip const rhs = if (is_longlong or is_signed) blk: { // check if long long first so that signed long long doesn't just become unsigned long long const typeid_node = if (is_longlong) try Tag.type.create(c.arena, "usize") else try transQualTypeIntWidthOf(c, subscr_qt, false); - break :blk try Tag.int_cast.create(c.arena, .{ .lhs = typeid_node, .rhs = try transExpr(c, scope, subscr_expr, .used) }); + break :blk try Tag.as.create(c.arena, .{ + .lhs = typeid_node, + .rhs = try Tag.int_cast.create( + c.arena, + try transExpr(c, scope, subscr_expr, .used), + ), + }); } else try transExpr(c, scope, subscr_expr, .used); const node = try Tag.array_access.create(c.arena, .{ @@ -3968,8 +4007,7 @@ fn transCreateCompoundAssign( } if (is_shift) { - const cast_to_type = try qualTypeToLog2IntRef(c, scope, rhs_qt, loc); - rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node }); + rhs_node = try Tag.int_cast.create(c.arena, rhs_node); } else if (requires_int_cast) { rhs_node = try transCCast(c, scope, loc, lhs_qt, rhs_qt, rhs_node); } @@ -4008,8 +4046,7 @@ fn transCreateCompoundAssign( try block_scope.statements.append(assign); } else { if (is_shift) { - const cast_to_type = try qualTypeToLog2IntRef(c, &block_scope.base, rhs_qt, loc); - rhs_node = try Tag.int_cast.create(c.arena, .{ .lhs = cast_to_type, .rhs = rhs_node }); + rhs_node = try Tag.int_cast.create(c.arena, rhs_node); } else if (requires_int_cast) { rhs_node = try transCCast(c, &block_scope.base, loc, lhs_qt, rhs_qt, rhs_node); } @@ -4029,7 +4066,10 @@ fn transCreateCompoundAssign( // Casting away const or volatile requires us to use @ptrFromInt fn removeCVQualifiers(c: *Context, dst_type_node: Node, expr: Node) Error!Node { const int_from_ptr = try Tag.int_from_ptr.create(c.arena, expr); - return Tag.ptr_from_int.create(c.arena, .{ .lhs = dst_type_node, .rhs = int_from_ptr }); + return Tag.as.create(c.arena, .{ + .lhs = dst_type_node, + .rhs = try Tag.ptr_from_int.create(c.arena, int_from_ptr), + }); } fn transCPtrCast( @@ -4062,11 +4102,12 @@ fn transCPtrCast( // For opaque types a ptrCast is enough expr else blk: { - const alignof = try Tag.std_meta_alignment.create(c.arena, dst_type_node); - const align_cast = try Tag.align_cast.create(c.arena, .{ .lhs = alignof, .rhs = expr }); - break :blk align_cast; + break :blk try Tag.align_cast.create(c.arena, expr); }; - return Tag.ptr_cast.create(c.arena, .{ .lhs = dst_type_node, .rhs = rhs }); + return Tag.as.create(c.arena, .{ + .lhs = dst_type_node, + .rhs = try Tag.ptr_cast.create(c.arena, rhs), + }); } } @@ -4337,19 +4378,6 @@ fn qualTypeIntBitWidth(c: *Context, qt: clang.QualType) !u32 { } } -fn qualTypeToLog2IntRef(c: *Context, scope: *Scope, qt: clang.QualType, source_loc: clang.SourceLocation) !Node { - const int_bit_width = try qualTypeIntBitWidth(c, qt); - - if (int_bit_width != 0) { - // we can perform the log2 now. - const cast_bit_width = math.log2_int(u64, int_bit_width); - return Tag.log2_int_type.create(c.arena, cast_bit_width); - } - - const zig_type = try transQualType(c, scope, qt, source_loc); - return Tag.std_math_Log2Int.create(c.arena, zig_type); -} - fn qualTypeChildIsFnProto(qt: clang.QualType) bool { const ty = qualTypeCanon(qt); @@ -4731,14 +4759,12 @@ fn transCreateNodeShiftOp( const lhs_expr = stmt.getLHS(); const rhs_expr = stmt.getRHS(); - const rhs_location = rhs_expr.getBeginLoc(); // lhs >> @as(u5, rh) const lhs = try transExpr(c, scope, lhs_expr, .used); - const rhs_type = try qualTypeToLog2IntRef(c, scope, stmt.getType(), rhs_location); const rhs = try transExprCoercing(c, scope, rhs_expr, .used); - const rhs_casted = try Tag.int_cast.create(c.arena, .{ .lhs = rhs_type, .rhs = rhs }); + const rhs_casted = try Tag.int_cast.create(c.arena, rhs); return transCreateNodeInfixOp(c, op, lhs, rhs_casted, used); } @@ -6513,9 +6539,9 @@ fn parseCPostfixExpr(c: *Context, m: *MacroCtx, scope: *Scope, type_name: ?Node) }, .LBracket => { const index_val = try macroIntFromBool(c, try parseCExpr(c, m, scope)); - const index = try Tag.int_cast.create(c.arena, .{ + const index = try Tag.as.create(c.arena, .{ .lhs = try Tag.type.create(c.arena, "usize"), - .rhs = index_val, + .rhs = try Tag.int_cast.create(c.arena, index_val), }); node = try Tag.array_access.create(c.arena, .{ .lhs = node, .rhs = index }); try m.skip(c, .RBracket); diff --git a/src/translate_c/ast.zig b/src/translate_c/ast.zig index c8ccfa497f..a24bff0176 100644 --- a/src/translate_c/ast.zig +++ b/src/translate_c/ast.zig @@ -115,15 +115,10 @@ pub const Node = extern union { /// @import("std").zig.c_builtins. import_c_builtin, - log2_int_type, - /// @import("std").math.Log2Int(operand) - std_math_Log2Int, - /// @intCast(lhs, rhs) + /// @intCast(operand) int_cast, /// @import("std").zig.c_translation.promoteIntLiteral(value, type, base) helpers_promoteIntLiteral, - /// @import("std").meta.alignment(value) - std_meta_alignment, /// @import("std").zig.c_translation.signedRemainder(lhs, rhs) signed_remainder, /// @divTrunc(lhs, rhs) @@ -132,23 +127,23 @@ pub const Node = extern union { int_from_bool, /// @as(lhs, rhs) as, - /// @truncate(lhs, rhs) + /// @truncate(operand) truncate, - /// @bitCast(lhs, rhs) + /// @bitCast(operand) bit_cast, - /// @floatCast(lhs, rhs) + /// @floatCast(operand) float_cast, - /// @intFromFloat(lhs, rhs) + /// @intFromFloat(operand) int_from_float, - /// @floatFromInt(lhs, rhs) + /// @floatFromInt(operand) float_from_int, - /// @ptrFromInt(lhs, rhs) + /// @ptrFromInt(operand) ptr_from_int, /// @intFromPtr(operand) int_from_ptr, - /// @alignCast(lhs, rhs) + /// @alignCast(operand) align_cast, - /// @ptrCast(lhs, rhs) + /// @ptrCast(operand) ptr_cast, /// @divExact(lhs, rhs) div_exact, @@ -254,7 +249,6 @@ pub const Node = extern union { .@"comptime", .@"defer", .asm_simple, - .std_math_Log2Int, .negate, .negate_wrap, .bit_not, @@ -270,12 +264,20 @@ pub const Node = extern union { .switch_else, .block_single, .helpers_sizeof, - .std_meta_alignment, .int_from_bool, .sizeof, .alignof, .typeof, .typeinfo, + .align_cast, + .truncate, + .bit_cast, + .float_cast, + .int_from_float, + .float_from_int, + .ptr_from_int, + .ptr_cast, + .int_cast, => Payload.UnOp, .add, @@ -314,24 +316,15 @@ pub const Node = extern union { .bit_xor_assign, .div_trunc, .signed_remainder, - .int_cast, .as, - .truncate, - .bit_cast, - .float_cast, - .int_from_float, - .float_from_int, - .ptr_from_int, .array_cat, .ellipsis3, .assign, - .align_cast, .array_access, .std_mem_zeroinit, .helpers_flexible_array_type, .helpers_shuffle_vector_index, .vector, - .ptr_cast, .div_exact, .offset_of, .helpers_cast, @@ -367,7 +360,6 @@ pub const Node = extern union { .c_pointer, .single_pointer => Payload.Pointer, .array_type, .null_sentinel_array_type => Payload.Array, .arg_redecl, .alias, .fail_decl => Payload.ArgRedecl, - .log2_int_type => Payload.Log2IntType, .var_simple, .pub_var_simple, .static_local_var, .mut_str => Payload.SimpleVarDecl, .enum_constant => Payload.EnumConstant, .array_filler => Payload.ArrayFiller, @@ -644,11 +636,6 @@ pub const Payload = struct { }, }; - pub const Log2IntType = struct { - base: Payload, - data: std.math.Log2Int(u64), - }; - pub const SimpleVarDecl = struct { base: Payload, data: struct { @@ -885,11 +872,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { try c.buf.append('\n'); return @as(NodeIndex, 0); // error: integer value 0 cannot be coerced to type 'std.mem.Allocator.Error!u32' }, - .std_math_Log2Int => { - const payload = node.castTag(.std_math_Log2Int).?.data; - const import_node = try renderStdImport(c, &.{ "math", "Log2Int" }); - return renderCall(c, import_node, &.{payload}); - }, .helpers_cast => { const payload = node.castTag(.helpers_cast).?.data; const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "cast" }); @@ -900,11 +882,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "promoteIntLiteral" }); return renderCall(c, import_node, &.{ payload.type, payload.value, payload.base }); }, - .std_meta_alignment => { - const payload = node.castTag(.std_meta_alignment).?.data; - const import_node = try renderStdImport(c, &.{ "meta", "alignment" }); - return renderCall(c, import_node, &.{payload}); - }, .helpers_sizeof => { const payload = node.castTag(.helpers_sizeof).?.data; const import_node = try renderStdImport(c, &.{ "zig", "c_translation", "sizeof" }); @@ -1081,14 +1058,6 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { .data = undefined, }); }, - .log2_int_type => { - const payload = node.castTag(.log2_int_type).?.data; - return c.addNode(.{ - .tag = .identifier, - .main_token = try c.addTokenFmt(.identifier, "u{d}", .{payload}), - .data = undefined, - }); - }, .identifier => { const payload = node.castTag(.identifier).?.data; return c.addNode(.{ @@ -1344,7 +1313,7 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { }, .int_cast => { const payload = node.castTag(.int_cast).?.data; - return renderBuiltinCall(c, "@intCast", &.{ payload.lhs, payload.rhs }); + return renderBuiltinCall(c, "@intCast", &.{payload}); }, .signed_remainder => { const payload = node.castTag(.signed_remainder).?.data; @@ -1365,27 +1334,27 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { }, .truncate => { const payload = node.castTag(.truncate).?.data; - return renderBuiltinCall(c, "@truncate", &.{ payload.lhs, payload.rhs }); + return renderBuiltinCall(c, "@truncate", &.{payload}); }, .bit_cast => { const payload = node.castTag(.bit_cast).?.data; - return renderBuiltinCall(c, "@bitCast", &.{ payload.lhs, payload.rhs }); + return renderBuiltinCall(c, "@bitCast", &.{payload}); }, .float_cast => { const payload = node.castTag(.float_cast).?.data; - return renderBuiltinCall(c, "@floatCast", &.{ payload.lhs, payload.rhs }); + return renderBuiltinCall(c, "@floatCast", &.{payload}); }, .int_from_float => { const payload = node.castTag(.int_from_float).?.data; - return renderBuiltinCall(c, "@intFromFloat", &.{ payload.lhs, payload.rhs }); + return renderBuiltinCall(c, "@intFromFloat", &.{payload}); }, .float_from_int => { const payload = node.castTag(.float_from_int).?.data; - return renderBuiltinCall(c, "@floatFromInt", &.{ payload.lhs, payload.rhs }); + return renderBuiltinCall(c, "@floatFromInt", &.{payload}); }, .ptr_from_int => { const payload = node.castTag(.ptr_from_int).?.data; - return renderBuiltinCall(c, "@ptrFromInt", &.{ payload.lhs, payload.rhs }); + return renderBuiltinCall(c, "@ptrFromInt", &.{payload}); }, .int_from_ptr => { const payload = node.castTag(.int_from_ptr).?.data; @@ -1393,11 +1362,11 @@ fn renderNode(c: *Context, node: Node) Allocator.Error!NodeIndex { }, .align_cast => { const payload = node.castTag(.align_cast).?.data; - return renderBuiltinCall(c, "@alignCast", &.{ payload.lhs, payload.rhs }); + return renderBuiltinCall(c, "@alignCast", &.{payload}); }, .ptr_cast => { const payload = node.castTag(.ptr_cast).?.data; - return renderBuiltinCall(c, "@ptrCast", &.{ payload.lhs, payload.rhs }); + return renderBuiltinCall(c, "@ptrCast", &.{payload}); }, .div_exact => { const payload = node.castTag(.div_exact).?.data; @@ -2330,14 +2299,11 @@ fn renderNodeGrouped(c: *Context, node: Node) !NodeIndex { .float_from_int, .ptr_from_int, .std_mem_zeroes, - .std_math_Log2Int, - .log2_int_type, .int_from_ptr, .sizeof, .alignof, .typeof, .typeinfo, - .std_meta_alignment, .vector, .helpers_sizeof, .helpers_cast,