aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-04-12 21:01:07 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-04-15 19:06:39 -0700
commit69645e28171829a3c53ee5359e08562bddd174f7 (patch)
treef967874ad60b0142c770c223d13ef9e483ee4ce9 /src
parent0e50a0c1e53a062e7c68ceeb1cfab9597a9caa23 (diff)
downloadzig-69645e28171829a3c53ee5359e08562bddd174f7.tar.gz
zig-69645e28171829a3c53ee5359e08562bddd174f7.zip
stage2: implement `@sizeOf`
Diffstat (limited to 'src')
-rw-r--r--src/AstGen.zig8
-rw-r--r--src/Sema.zig11
-rw-r--r--src/zir.zig4
3 files changed, 22 insertions, 1 deletions
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,