Address Spaces: decl_ref, *?T => *T, and *(E!T) -> *T

This commit is contained in:
Robin Voetter 2021-08-20 02:53:29 +02:00
parent 6023108650
commit cd9f6001af
3 changed files with 69 additions and 5 deletions

View File

@ -353,7 +353,7 @@ pub const Decl = struct {
/// to require re-analysis.
outdated,
},
/// Whether `typed_value`, `align_val`, `linksection_val` and `has_addrspace` are populated.
/// Whether `typed_value`, `align_val`, `linksection_val` and `addrspace` are populated.
has_tv: bool,
/// If `true` it means the `Decl` is the resource owner of the type/value associated
/// with it. That means when `Decl` is destroyed, the cleanup code should additionally
@ -4401,6 +4401,34 @@ pub fn ptrType(
});
}
/// Create a pointer type with an explicit address space. This function might return results
/// of either simplePtrType or ptrType, depending on the address space.
/// TODO(Snektron) unify ptrType functions.
pub fn simplePtrTypeWithAddressSpace(
arena: *Allocator,
elem_ty: Type,
mutable: bool,
size: std.builtin.TypeInfo.Pointer.Size,
address_space: std.builtin.AddressSpace,
) Allocator.Error!Type {
switch (address_space) {
.generic => return simplePtrType(arena, elem_ty, mutable, size),
else => return ptrType(
arena,
elem_ty,
null,
0,
address_space,
0,
0,
mutable,
false,
false,
size,
),
}
}
pub fn optionalType(arena: *Allocator, child_type: Type) Allocator.Error!Type {
switch (child_type.tag()) {
.single_const_pointer => return Type.Tag.optional_single_const_pointer.create(

View File

@ -3658,7 +3658,13 @@ fn zirOptionalPayloadPtr(
}
const child_type = try opt_type.optionalChildAlloc(sema.arena);
const child_pointer = try Module.simplePtrType(sema.arena, child_type, !optional_ptr_ty.isConstPtr(), .One);
const child_pointer = try Module.simplePtrTypeWithAddressSpace(
sema.arena,
child_type,
!optional_ptr_ty.isConstPtr(),
.One,
optional_ptr_ty.ptrAddressSpace(),
);
if (try sema.resolveDefinedValue(block, src, optional_ptr)) |pointer_val| {
if (try pointer_val.pointerDeref(sema.arena)) |val| {
@ -3773,7 +3779,13 @@ fn zirErrUnionPayloadPtr(
return sema.mod.fail(&block.base, src, "expected error union type, found {}", .{operand_ty.elemType()});
const payload_ty = operand_ty.elemType().errorUnionPayload();
const operand_pointer_ty = try Module.simplePtrType(sema.arena, payload_ty, !operand_ty.isConstPtr(), .One);
const operand_pointer_ty = try Module.simplePtrTypeWithAddressSpace(
sema.arena,
payload_ty,
!operand_ty.isConstPtr(),
.One,
operand_ty.ptrAddressSpace(),
);
if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| {
if (try pointer_val.pointerDeref(sema.arena)) |val| {
@ -9525,11 +9537,11 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {
const decl_tv = try decl.typedValue();
if (decl_tv.val.castTag(.variable)) |payload| {
const variable = payload.data;
const ty = try Module.simplePtrType(sema.arena, decl_tv.ty, variable.is_mutable, .One);
const ty = try Module.simplePtrTypeWithAddressSpace(sema.arena, decl_tv.ty, variable.is_mutable, .One, decl.@"addrspace");
return sema.addConstant(ty, try Value.Tag.decl_ref.create(sema.arena, decl));
}
return sema.addConstant(
try Module.simplePtrType(sema.arena, decl_tv.ty, false, .One),
try Module.simplePtrTypeWithAddressSpace(sema.arena, decl_tv.ty, false, .One, decl.@"addrspace"),
try Value.Tag.decl_ref.create(sema.arena, decl),
);
}

View File

@ -1526,6 +1526,30 @@ pub const Type = extern union {
}
}
pub fn ptrAddressSpace(self: Type) std.builtin.AddressSpace {
return switch (self.tag()) {
.single_const_pointer_to_comptime_int,
.const_slice_u8,
.single_const_pointer,
.single_mut_pointer,
.many_const_pointer,
.many_mut_pointer,
.c_const_pointer,
.c_mut_pointer,
.const_slice,
.mut_slice,
.inferred_alloc_const,
.inferred_alloc_mut,
.manyptr_u8,
.manyptr_const_u8,
=> .generic,
.pointer => self.castTag(.pointer).?.data.@"addrspace",
else => unreachable,
};
}
/// Asserts that hasCodeGenBits() is true.
pub fn abiAlignment(self: Type, target: Target) u32 {
return switch (self.tag()) {