Commit 447ca4e3ff
Changed files (2)
src
translate_c
src/translate_c/ast.zig
@@ -115,15 +115,10 @@ pub const Node = extern union {
/// @import("std").zig.c_builtins.<name>
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,
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);