Commit 69645e2817

Andrew Kelley <andrew@ziglang.org>
2021-04-13 06:01:07
stage2: implement `@sizeOf`
1 parent 0e50a0c
Changed files (3)
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,
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();
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,