diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-10-21 22:56:11 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-10-21 22:56:11 -0700 |
| commit | 0a6851cc6de540ed95c3ec1c78eb3da7897bd930 (patch) | |
| tree | b929564a7b7cddafd8dfb5ad9157fffe3425a1f0 /src/type.zig | |
| parent | 1bce0ed0460e2bdeb47d534e28090ed4b3794b97 (diff) | |
| download | zig-0a6851cc6de540ed95c3ec1c78eb3da7897bd930.tar.gz zig-0a6851cc6de540ed95c3ec1c78eb3da7897bd930.zip | |
stage2: implement comptime loads through casted pointers
Diffstat (limited to 'src/type.zig')
| -rw-r--r-- | src/type.zig | 93 |
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).?; } |
