aboutsummaryrefslogtreecommitdiff
path: root/src/type.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-10-21 22:56:11 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-10-21 22:56:11 -0700
commit0a6851cc6de540ed95c3ec1c78eb3da7897bd930 (patch)
treeb929564a7b7cddafd8dfb5ad9157fffe3425a1f0 /src/type.zig
parent1bce0ed0460e2bdeb47d534e28090ed4b3794b97 (diff)
downloadzig-0a6851cc6de540ed95c3ec1c78eb3da7897bd930.tar.gz
zig-0a6851cc6de540ed95c3ec1c78eb3da7897bd930.zip
stage2: implement comptime loads through casted pointers
Diffstat (limited to 'src/type.zig')
-rw-r--r--src/type.zig93
1 files changed, 50 insertions, 43 deletions
diff --git a/src/type.zig b/src/type.zig
index 72347f5adc..380c75ca77 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -1764,6 +1764,7 @@ pub const Type = extern union {
}
/// Asserts the type has the ABI size already resolved.
+ /// Types that return false for hasCodeGenBits() return 0.
pub fn abiSize(self: Type, target: Target) u64 {
return switch (self.tag()) {
.fn_noreturn_no_args => unreachable, // represents machine code; not a pointer
@@ -1771,53 +1772,32 @@ pub const Type = extern union {
.fn_naked_noreturn_no_args => unreachable, // represents machine code; not a pointer
.fn_ccc_void_no_args => unreachable, // represents machine code; not a pointer
.function => unreachable, // represents machine code; not a pointer
- .c_void => unreachable,
- .type => unreachable,
- .comptime_int => unreachable,
- .comptime_float => unreachable,
+ .@"opaque" => unreachable, // no size available
+ .bound_fn => unreachable, // TODO remove from the language
.noreturn => unreachable,
- .@"null" => unreachable,
- .@"undefined" => unreachable,
- .enum_literal => unreachable,
- .single_const_pointer_to_comptime_int => unreachable,
- .empty_struct_literal => unreachable,
.inferred_alloc_const => unreachable,
.inferred_alloc_mut => unreachable,
- .@"opaque" => unreachable,
.var_args_param => unreachable,
.generic_poison => unreachable,
- .type_info => unreachable,
- .bound_fn => unreachable,
-
- .empty_struct, .void => 0,
+ .call_options => unreachable, // missing call to resolveTypeFields
+ .export_options => unreachable, // missing call to resolveTypeFields
+ .extern_options => unreachable, // missing call to resolveTypeFields
+ .type_info => unreachable, // missing call to resolveTypeFields
- .@"struct" => {
- const fields = self.structFields();
- if (self.castTag(.@"struct")) |payload| {
- const struct_obj = payload.data;
- assert(struct_obj.status == .have_layout);
- const is_packed = struct_obj.layout == .Packed;
- if (is_packed) @panic("TODO packed structs");
- }
- var size: u64 = 0;
- var big_align: u32 = 0;
- for (fields.values()) |field| {
- if (!field.ty.hasCodeGenBits()) continue;
+ .c_void,
+ .type,
+ .comptime_int,
+ .comptime_float,
+ .@"null",
+ .@"undefined",
+ .enum_literal,
+ .single_const_pointer_to_comptime_int,
+ .empty_struct_literal,
+ .empty_struct,
+ .void,
+ => 0,
- const field_align = a: {
- if (field.abi_align.tag() == .abi_align_default) {
- break :a field.ty.abiAlignment(target);
- } else {
- break :a @intCast(u32, field.abi_align.toUnsignedInt());
- }
- };
- big_align = @maximum(big_align, field_align);
- size = std.mem.alignForwardGeneric(u64, size, field_align);
- size += field.ty.abiSize(target);
- }
- size = std.mem.alignForwardGeneric(u64, size, big_align);
- return size;
- },
+ .@"struct" => return self.structFieldOffset(self.structFieldCount(), target),
.enum_simple, .enum_full, .enum_nonexhaustive, .enum_numbered => {
var buffer: Payload.Bits = undefined;
const int_tag_ty = self.intTagType(&buffer);
@@ -1837,9 +1817,6 @@ pub const Type = extern union {
.address_space,
.float_mode,
.reduce_op,
- .call_options,
- .export_options,
- .extern_options,
=> return 1,
.array_u8 => self.castTag(.array_u8).?.data,
@@ -3414,6 +3391,36 @@ pub const Type = extern union {
}
}
+ pub fn structFieldOffset(ty: Type, index: usize, target: Target) u64 {
+ const fields = ty.structFields();
+ if (ty.castTag(.@"struct")) |payload| {
+ const struct_obj = payload.data;
+ assert(struct_obj.status == .have_layout);
+ const is_packed = struct_obj.layout == .Packed;
+ if (is_packed) @panic("TODO packed structs");
+ }
+
+ var offset: u64 = 0;
+ var big_align: u32 = 0;
+ for (fields.values()) |field, i| {
+ if (!field.ty.hasCodeGenBits()) continue;
+
+ const field_align = a: {
+ if (field.abi_align.tag() == .abi_align_default) {
+ break :a field.ty.abiAlignment(target);
+ } else {
+ break :a @intCast(u32, field.abi_align.toUnsignedInt());
+ }
+ };
+ big_align = @maximum(big_align, field_align);
+ offset = std.mem.alignForwardGeneric(u64, offset, field_align);
+ if (i == index) return offset;
+ offset += field.ty.abiSize(target);
+ }
+ offset = std.mem.alignForwardGeneric(u64, offset, big_align);
+ return offset;
+ }
+
pub fn declSrcLoc(ty: Type) Module.SrcLoc {
return declSrcLocOrNull(ty).?;
}