diff --git a/src/AstGen.zig b/src/AstGen.zig index fff0d6336d..0830b95e77 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1359,6 +1359,7 @@ fn blockExprStmts( .int_to_enum, .enum_to_int, .type_info, + .size_of, => break :b false, // ZIR instructions that are always either `noreturn` or `void`. @@ -4342,6 +4343,12 @@ fn builtinCall( return rvalue(gz, scope, rl, result, node); }, + .size_of => { + const operand = try typeExpr(gz, scope, params[0]); + const result = try gz.addUnNode(.size_of, operand, node); + return rvalue(gz, scope, rl, result, node); + }, + .add_with_overflow, .align_cast, .align_of, @@ -4396,7 +4403,6 @@ fn builtinCall( .shl_with_overflow, .shr_exact, .shuffle, - .size_of, .splat, .reduce, .src, diff --git a/src/Sema.zig b/src/Sema.zig index df19eb913d..3dd16a6033 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -264,6 +264,7 @@ pub fn analyzeBody( .switch_capture_else => try sema.zirSwitchCaptureElse(block, inst, false), .switch_capture_else_ref => try sema.zirSwitchCaptureElse(block, inst, true), .type_info => try sema.zirTypeInfo(block, inst), + .size_of => try sema.zirSizeOf(block, inst), .typeof => try sema.zirTypeof(block, inst), .typeof_elem => try sema.zirTypeofElem(block, inst), .typeof_peer => try sema.zirTypeofPeer(block, inst), @@ -4347,6 +4348,16 @@ fn zirCmp( return block.addBinOp(src, bool_type, tag, casted_lhs, casted_rhs); } +fn zirSizeOf(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { + const inst_data = sema.code.instructions.items(.data)[inst].un_node; + const src = inst_data.src(); + const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; + const operand_ty = try sema.resolveType(block, operand_src, inst_data.operand); + const target = sema.mod.getTarget(); + const abi_size = operand_ty.abiSize(target); + return sema.mod.constIntUnsigned(sema.arena, src, Type.initTag(.comptime_int), abi_size); +} + fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst { const inst_data = sema.code.instructions.items(.data)[inst].un_node; const src = inst_data.src(); diff --git a/src/zir.zig b/src/zir.zig index c5c1905621..075a09a239 100644 --- a/src/zir.zig +++ b/src/zir.zig @@ -695,6 +695,8 @@ pub const Inst = struct { enum_to_int, /// Implements the `@typeInfo` builtin. Uses `un_node`. type_info, + /// Implements the `@sizeOf` builtin. Uses `un_node`. + size_of, /// Returns whether the instruction is one of the control flow "noreturn" types. /// Function calls do not count. @@ -861,6 +863,7 @@ pub const Inst = struct { .int_to_enum, .enum_to_int, .type_info, + .size_of, => false, .@"break", @@ -1670,6 +1673,7 @@ const Writer = struct { .struct_init_empty, .enum_to_int, .type_info, + .size_of, => try self.writeUnNode(stream, inst), .ref,