mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
Address Spaces: Yeet address space on function prototypes
This is a property which solely belongs to pointers to functions, not to the functions themselves. This cannot be properly represented by stage 2 at the moment, as type with zigTypeTag() == .Fn is overloaded for for function pointers and function prototypes.
This commit is contained in:
parent
5a142dfa56
commit
95e83afa98
10 changed files with 180 additions and 209 deletions
|
|
@ -365,7 +365,6 @@ pub const TypeInfo = union(enum) {
|
|||
pub const Fn = struct {
|
||||
calling_convention: CallingConvention,
|
||||
alignment: comptime_int,
|
||||
address_space: AddressSpace,
|
||||
is_generic: bool,
|
||||
is_var_args: bool,
|
||||
return_type: ?type,
|
||||
|
|
|
|||
|
|
@ -1117,9 +1117,9 @@ fn fnProtoExpr(
|
|||
break :inst try expr(gz, scope, align_rl, fn_proto.ast.align_expr);
|
||||
};
|
||||
|
||||
const addrspace_inst: Zir.Inst.Ref = if (fn_proto.ast.addrspace_expr == 0) .none else inst: {
|
||||
break :inst try expr(gz, scope, .{ .ty = .address_space_type }, fn_proto.ast.addrspace_expr);
|
||||
};
|
||||
if (fn_proto.ast.addrspace_expr != 0) {
|
||||
return astgen.failNode(fn_proto.ast.addrspace_expr, "addrspace not allowed on function prototypes", .{});
|
||||
}
|
||||
|
||||
if (fn_proto.ast.section_expr != 0) {
|
||||
return astgen.failNode(fn_proto.ast.section_expr, "linksection not allowed on function prototypes", .{});
|
||||
|
|
@ -1153,7 +1153,6 @@ fn fnProtoExpr(
|
|||
.body = &[0]Zir.Inst.Index{},
|
||||
.cc = cc,
|
||||
.align_inst = align_inst,
|
||||
.addrspace_inst = addrspace_inst,
|
||||
.lib_name = 0,
|
||||
.is_var_args = is_var_args,
|
||||
.is_inferred_error = false,
|
||||
|
|
@ -3089,7 +3088,6 @@ fn fnDecl(
|
|||
.body = &[0]Zir.Inst.Index{},
|
||||
.cc = cc,
|
||||
.align_inst = .none, // passed in the per-decl data
|
||||
.addrspace_inst = .none, // passed in the per-decl data
|
||||
.lib_name = lib_name,
|
||||
.is_var_args = is_var_args,
|
||||
.is_inferred_error = false,
|
||||
|
|
@ -3129,7 +3127,6 @@ fn fnDecl(
|
|||
.body = fn_gz.instructions.items,
|
||||
.cc = cc,
|
||||
.align_inst = .none, // passed in the per-decl data
|
||||
.addrspace_inst = .none, // passed in the per-decl data
|
||||
.lib_name = lib_name,
|
||||
.is_var_args = is_var_args,
|
||||
.is_inferred_error = is_inferred_error,
|
||||
|
|
@ -3481,7 +3478,6 @@ fn testDecl(
|
|||
.body = fn_block.instructions.items,
|
||||
.cc = .none,
|
||||
.align_inst = .none,
|
||||
.addrspace_inst = .none,
|
||||
.lib_name = 0,
|
||||
.is_var_args = false,
|
||||
.is_inferred_error = true,
|
||||
|
|
@ -9217,7 +9213,6 @@ const GenZir = struct {
|
|||
ret_br: Zir.Inst.Index,
|
||||
cc: Zir.Inst.Ref,
|
||||
align_inst: Zir.Inst.Ref,
|
||||
addrspace_inst: Zir.Inst.Ref,
|
||||
lib_name: u32,
|
||||
is_var_args: bool,
|
||||
is_inferred_error: bool,
|
||||
|
|
@ -9261,7 +9256,7 @@ const GenZir = struct {
|
|||
|
||||
if (args.cc != .none or args.lib_name != 0 or
|
||||
args.is_var_args or args.is_test or args.align_inst != .none or
|
||||
args.addrspace_inst != .none or args.is_extern)
|
||||
args.is_extern)
|
||||
{
|
||||
try astgen.extra.ensureUnusedCapacity(
|
||||
gpa,
|
||||
|
|
@ -9269,7 +9264,6 @@ const GenZir = struct {
|
|||
args.ret_ty.len + args.body.len + src_locs.len +
|
||||
@boolToInt(args.lib_name != 0) +
|
||||
@boolToInt(args.align_inst != .none) +
|
||||
@boolToInt(args.addrspace_inst != .none) +
|
||||
@boolToInt(args.cc != .none),
|
||||
);
|
||||
const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.ExtendedFunc{
|
||||
|
|
@ -9287,9 +9281,6 @@ const GenZir = struct {
|
|||
if (args.align_inst != .none) {
|
||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.align_inst));
|
||||
}
|
||||
if (args.addrspace_inst != .none) {
|
||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.addrspace_inst));
|
||||
}
|
||||
astgen.extra.appendSliceAssumeCapacity(args.ret_ty);
|
||||
astgen.extra.appendSliceAssumeCapacity(args.body);
|
||||
astgen.extra.appendSliceAssumeCapacity(src_locs);
|
||||
|
|
@ -9308,7 +9299,6 @@ const GenZir = struct {
|
|||
.has_lib_name = args.lib_name != 0,
|
||||
.has_cc = args.cc != .none,
|
||||
.has_align = args.align_inst != .none,
|
||||
.has_addrspace = args.addrspace_inst != .none,
|
||||
.is_test = args.is_test,
|
||||
.is_extern = args.is_extern,
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -3220,7 +3220,12 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
|
|||
};
|
||||
|
||||
break :blk switch (decl.zirAddrspaceRef()) {
|
||||
.none => .generic,
|
||||
.none => switch (addrspace_ctx) {
|
||||
.function => target_util.defaultAddressSpace(sema.mod.getTarget(), .function),
|
||||
.variable => target_util.defaultAddressSpace(sema.mod.getTarget(), .global_mutable),
|
||||
.constant => target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),
|
||||
else => unreachable,
|
||||
},
|
||||
else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, src, addrspace_ref, addrspace_ctx),
|
||||
};
|
||||
};
|
||||
|
|
@ -4359,26 +4364,21 @@ pub fn simplePtrType(
|
|||
elem_ty: Type,
|
||||
mutable: bool,
|
||||
size: std.builtin.TypeInfo.Pointer.Size,
|
||||
@"addrspace": std.builtin.AddressSpace,
|
||||
) Allocator.Error!Type {
|
||||
if (!mutable and size == .Slice and elem_ty.eql(Type.initTag(.u8))) {
|
||||
return Type.initTag(.const_slice_u8);
|
||||
}
|
||||
// TODO stage1 type inference bug
|
||||
const T = Type.Tag;
|
||||
|
||||
const type_payload = try arena.create(Type.Payload.ElemType);
|
||||
type_payload.* = .{
|
||||
.base = .{
|
||||
.tag = switch (size) {
|
||||
.One => if (mutable) T.single_mut_pointer else T.single_const_pointer,
|
||||
.Many => if (mutable) T.many_mut_pointer else T.many_const_pointer,
|
||||
.C => if (mutable) T.c_mut_pointer else T.c_const_pointer,
|
||||
.Slice => if (mutable) T.mut_slice else T.const_slice,
|
||||
},
|
||||
},
|
||||
.data = elem_ty,
|
||||
};
|
||||
return Type.initPayload(&type_payload.base);
|
||||
return ptrType(
|
||||
arena,
|
||||
elem_ty,
|
||||
null,
|
||||
0,
|
||||
@"addrspace",
|
||||
0,
|
||||
0,
|
||||
mutable,
|
||||
false,
|
||||
false,
|
||||
size,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn ptrType(
|
||||
|
|
@ -4396,7 +4396,9 @@ pub fn ptrType(
|
|||
) Allocator.Error!Type {
|
||||
assert(host_size == 0 or bit_offset < host_size * 8);
|
||||
|
||||
// TODO check if type can be represented by simplePtrType
|
||||
if (sentinel != null or @"align" != 0 or @"addrspace" != .generic or
|
||||
bit_offset != 0 or host_size != 0 or @"allowzero" or @"volatile")
|
||||
{
|
||||
return Type.Tag.pointer.create(arena, .{
|
||||
.pointee_type = elem_ty,
|
||||
.sentinel = sentinel,
|
||||
|
|
@ -4409,34 +4411,28 @@ pub fn ptrType(
|
|||
.@"volatile" = @"volatile",
|
||||
.size = size,
|
||||
});
|
||||
}
|
||||
|
||||
/// 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,
|
||||
),
|
||||
}
|
||||
|
||||
if (!mutable and size == .Slice and elem_ty.eql(Type.initTag(.u8))) {
|
||||
return Type.initTag(.const_slice_u8);
|
||||
}
|
||||
|
||||
// TODO stage1 type inference bug
|
||||
const T = Type.Tag;
|
||||
|
||||
const type_payload = try arena.create(Type.Payload.ElemType);
|
||||
type_payload.* = .{
|
||||
.base = .{
|
||||
.tag = switch (size) {
|
||||
.One => if (mutable) T.single_mut_pointer else T.single_const_pointer,
|
||||
.Many => if (mutable) T.many_mut_pointer else T.many_const_pointer,
|
||||
.C => if (mutable) T.c_mut_pointer else T.c_const_pointer,
|
||||
.Slice => if (mutable) T.mut_slice else T.const_slice,
|
||||
},
|
||||
},
|
||||
.data = elem_ty,
|
||||
};
|
||||
return Type.initPayload(&type_payload.base);
|
||||
}
|
||||
|
||||
pub fn optionalType(arena: *Allocator, child_type: Type) Allocator.Error!Type {
|
||||
|
|
|
|||
121
src/Sema.zig
121
src/Sema.zig
|
|
@ -1373,7 +1373,13 @@ fn zirRetPtr(
|
|||
return sema.analyzeComptimeAlloc(block, sema.fn_ret_ty);
|
||||
}
|
||||
|
||||
const ptr_type = try Module.simplePtrType(sema.arena, sema.fn_ret_ty, true, .One);
|
||||
const ptr_type = try Module.simplePtrType(
|
||||
sema.arena,
|
||||
sema.fn_ret_ty,
|
||||
true,
|
||||
.One,
|
||||
target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
|
||||
);
|
||||
return block.addTy(.alloc, ptr_type);
|
||||
}
|
||||
|
||||
|
|
@ -1521,7 +1527,13 @@ fn zirAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError
|
|||
const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = inst_data.src_node };
|
||||
const var_decl_src = inst_data.src();
|
||||
const var_type = try sema.resolveType(block, ty_src, inst_data.operand);
|
||||
const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One);
|
||||
const ptr_type = try Module.simplePtrType(
|
||||
sema.arena,
|
||||
var_type,
|
||||
true,
|
||||
.One,
|
||||
target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
|
||||
);
|
||||
try sema.requireRuntimeBlock(block, var_decl_src);
|
||||
return block.addTy(.alloc, ptr_type);
|
||||
}
|
||||
|
|
@ -1538,7 +1550,13 @@ fn zirAllocMut(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
|
|||
return sema.analyzeComptimeAlloc(block, var_type);
|
||||
}
|
||||
try sema.validateVarType(block, ty_src, var_type);
|
||||
const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One);
|
||||
const ptr_type = try Module.simplePtrType(
|
||||
sema.arena,
|
||||
var_type,
|
||||
true,
|
||||
.One,
|
||||
target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
|
||||
);
|
||||
try sema.requireRuntimeBlock(block, var_decl_src);
|
||||
return block.addTy(.alloc, ptr_type);
|
||||
}
|
||||
|
|
@ -1598,7 +1616,13 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde
|
|||
try sema.mod.declareDeclDependency(sema.owner_decl, decl);
|
||||
|
||||
const final_elem_ty = try decl.ty.copy(sema.arena);
|
||||
const final_ptr_ty = try Module.simplePtrType(sema.arena, final_elem_ty, true, .One);
|
||||
const final_ptr_ty = try Module.simplePtrType(
|
||||
sema.arena,
|
||||
final_elem_ty,
|
||||
true,
|
||||
.One,
|
||||
target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
|
||||
);
|
||||
const final_ptr_ty_inst = try sema.addType(final_ptr_ty);
|
||||
sema.air_instructions.items(.data)[ptr_inst].ty_pl.ty = final_ptr_ty_inst;
|
||||
|
||||
|
|
@ -1620,7 +1644,13 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Inde
|
|||
try sema.validateVarType(block, ty_src, final_elem_ty);
|
||||
}
|
||||
// Change it to a normal alloc.
|
||||
const final_ptr_ty = try Module.simplePtrType(sema.arena, final_elem_ty, true, .One);
|
||||
const final_ptr_ty = try Module.simplePtrType(
|
||||
sema.arena,
|
||||
final_elem_ty,
|
||||
true,
|
||||
.One,
|
||||
target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
|
||||
);
|
||||
sema.air_instructions.set(ptr_inst, .{
|
||||
.tag = .alloc,
|
||||
.data = .{ .ty = final_ptr_ty },
|
||||
|
|
@ -1774,7 +1804,14 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Co
|
|||
}
|
||||
const ptr = sema.resolveInst(bin_inst.lhs);
|
||||
const value = sema.resolveInst(bin_inst.rhs);
|
||||
const ptr_ty = try Module.simplePtrType(sema.arena, sema.typeOf(value), true, .One);
|
||||
const ptr_ty = try Module.simplePtrType(
|
||||
sema.arena,
|
||||
sema.typeOf(value),
|
||||
true,
|
||||
.One,
|
||||
// TODO figure out which address space is appropriate here
|
||||
target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
|
||||
);
|
||||
// TODO detect when this store should be done at compile-time. For example,
|
||||
// if expressions should force it when the condition is compile-time known.
|
||||
const src: LazySrcLoc = .unneeded;
|
||||
|
|
@ -1821,7 +1858,14 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index)
|
|||
// for the inferred allocation.
|
||||
try inferred_alloc.data.stored_inst_list.append(sema.arena, operand);
|
||||
// Create a runtime bitcast instruction with exactly the type the pointer wants.
|
||||
const ptr_ty = try Module.simplePtrType(sema.arena, operand_ty, true, .One);
|
||||
const ptr_ty = try Module.simplePtrType(
|
||||
sema.arena,
|
||||
operand_ty,
|
||||
true,
|
||||
.One,
|
||||
// TODO figure out which address space is appropriate here
|
||||
target_util.defaultAddressSpace(sema.mod.getTarget(), .local),
|
||||
);
|
||||
const bitcasted_ptr = try block.addTyOp(.bitcast, ptr_ty, ptr);
|
||||
return sema.storePtr(block, src, bitcasted_ptr, operand);
|
||||
}
|
||||
|
|
@ -3658,7 +3702,7 @@ fn zirOptionalPayloadPtr(
|
|||
}
|
||||
|
||||
const child_type = try opt_type.optionalChildAlloc(sema.arena);
|
||||
const child_pointer = try Module.simplePtrTypeWithAddressSpace(
|
||||
const child_pointer = try Module.simplePtrType(
|
||||
sema.arena,
|
||||
child_type,
|
||||
!optional_ptr_ty.isConstPtr(),
|
||||
|
|
@ -3779,7 +3823,7 @@ 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.simplePtrTypeWithAddressSpace(
|
||||
const operand_pointer_ty = try Module.simplePtrType(
|
||||
sema.arena,
|
||||
payload_ty,
|
||||
!operand_ty.isConstPtr(),
|
||||
|
|
@ -3907,7 +3951,6 @@ fn zirFunc(
|
|||
ret_ty_body,
|
||||
cc,
|
||||
Value.initTag(.null_value),
|
||||
.generic,
|
||||
false,
|
||||
inferred_error_set,
|
||||
false,
|
||||
|
|
@ -3924,7 +3967,6 @@ fn funcCommon(
|
|||
ret_ty_body: []const Zir.Inst.Index,
|
||||
cc: std.builtin.CallingConvention,
|
||||
align_val: Value,
|
||||
address_space: std.builtin.AddressSpace,
|
||||
var_args: bool,
|
||||
inferred_error_set: bool,
|
||||
is_extern: bool,
|
||||
|
|
@ -3982,7 +4024,7 @@ fn funcCommon(
|
|||
// Hot path for some common function types.
|
||||
// TODO can we eliminate some of these Type tag values? seems unnecessarily complicated.
|
||||
if (!is_generic and block.params.items.len == 0 and !var_args and
|
||||
align_val.tag() == .null_value and !inferred_error_set and address_space == .generic)
|
||||
align_val.tag() == .null_value and !inferred_error_set)
|
||||
{
|
||||
if (bare_return_type.zigTypeTag() == .NoReturn and cc == .Unspecified) {
|
||||
break :fn_ty Type.initTag(.fn_noreturn_no_args);
|
||||
|
|
@ -4034,7 +4076,6 @@ fn funcCommon(
|
|||
.comptime_params = comptime_params.ptr,
|
||||
.return_type = return_type,
|
||||
.cc = cc,
|
||||
.@"addrspace" = address_space,
|
||||
.is_var_args = var_args,
|
||||
.is_generic = is_generic,
|
||||
});
|
||||
|
|
@ -6413,7 +6454,7 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
|
|||
|
||||
switch (ty.zigTypeTag()) {
|
||||
.Fn => {
|
||||
const field_values = try sema.arena.alloc(Value, 7);
|
||||
const field_values = try sema.arena.alloc(Value, 6);
|
||||
// calling_convention: CallingConvention,
|
||||
field_values[0] = try Value.Tag.enum_field_index.create(
|
||||
sema.arena,
|
||||
|
|
@ -6421,19 +6462,14 @@ fn zirTypeInfo(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
|
|||
);
|
||||
// alignment: comptime_int,
|
||||
field_values[1] = try Value.Tag.int_u64.create(sema.arena, ty.abiAlignment(target));
|
||||
// address_space: AddressSpace,
|
||||
field_values[2] = try Value.Tag.enum_field_index.create(
|
||||
sema.arena,
|
||||
@enumToInt(ty.fnAddressSpace()),
|
||||
);
|
||||
// is_generic: bool,
|
||||
field_values[3] = Value.initTag(.bool_false); // TODO
|
||||
field_values[2] = Value.initTag(.bool_false); // TODO
|
||||
// is_var_args: bool,
|
||||
field_values[4] = Value.initTag(.bool_false); // TODO
|
||||
field_values[3] = Value.initTag(.bool_false); // TODO
|
||||
// return_type: ?type,
|
||||
field_values[5] = try Value.Tag.ty.create(sema.arena, ty.fnReturnType());
|
||||
field_values[4] = try Value.Tag.ty.create(sema.arena, ty.fnReturnType());
|
||||
// args: []const FnArg,
|
||||
field_values[6] = Value.initTag(.null_value); // TODO
|
||||
field_values[5] = Value.initTag(.null_value); // TODO
|
||||
|
||||
return sema.addConstant(
|
||||
type_info_ty,
|
||||
|
|
@ -8063,7 +8099,6 @@ fn zirFuncExtended(
|
|||
const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
|
||||
const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = extra.data.src_node };
|
||||
const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align
|
||||
const addrspace_src: LazySrcLoc = src; // TODO(Snektron) add a LazySrcLoc that points at addrspace
|
||||
const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);
|
||||
|
||||
var extra_index: usize = extra.end;
|
||||
|
|
@ -8088,12 +8123,6 @@ fn zirFuncExtended(
|
|||
break :blk align_tv.val;
|
||||
} else Value.initTag(.null_value);
|
||||
|
||||
const address_space: std.builtin.AddressSpace = if (small.has_addrspace) blk: {
|
||||
const addrspace_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
break :blk try sema.analyzeAddrspace(block, addrspace_src, addrspace_ref, .function);
|
||||
} else .generic;
|
||||
|
||||
const ret_ty_body = sema.code.extra[extra_index..][0..extra.data.ret_body_len];
|
||||
extra_index += ret_ty_body.len;
|
||||
|
||||
|
|
@ -8116,7 +8145,6 @@ fn zirFuncExtended(
|
|||
ret_ty_body,
|
||||
cc,
|
||||
align_val,
|
||||
address_space,
|
||||
is_var_args,
|
||||
is_inferred_error,
|
||||
is_extern,
|
||||
|
|
@ -8309,7 +8337,13 @@ fn panicWithMsg(
|
|||
const panic_fn = try sema.getBuiltin(block, src, "panic");
|
||||
const unresolved_stack_trace_ty = try sema.getBuiltinType(block, src, "StackTrace");
|
||||
const stack_trace_ty = try sema.resolveTypeFields(block, src, unresolved_stack_trace_ty);
|
||||
const ptr_stack_trace_ty = try Module.simplePtrType(arena, stack_trace_ty, true, .One);
|
||||
const ptr_stack_trace_ty = try Module.simplePtrType(
|
||||
arena,
|
||||
stack_trace_ty,
|
||||
true,
|
||||
.One,
|
||||
target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant), // TODO might need a place that is more dynamic
|
||||
);
|
||||
const null_stack_trace = try sema.addConstant(
|
||||
try Module.optionalType(arena, ptr_stack_trace_ty),
|
||||
Value.initTag(.null_value),
|
||||
|
|
@ -8788,7 +8822,7 @@ fn structFieldPtr(
|
|||
const field_index = struct_obj.fields.getIndex(field_name) orelse
|
||||
return sema.failWithBadFieldAccess(block, struct_obj, field_name_src, field_name);
|
||||
const field = struct_obj.fields.values()[field_index];
|
||||
const ptr_field_ty = try Module.simplePtrTypeWithAddressSpace(
|
||||
const ptr_field_ty = try Module.simplePtrType(
|
||||
arena,
|
||||
field.ty,
|
||||
struct_ptr_ty.ptrIsMutable(),
|
||||
|
|
@ -8893,7 +8927,7 @@ fn unionFieldPtr(
|
|||
return sema.failWithBadUnionFieldAccess(block, union_obj, field_name_src, field_name);
|
||||
|
||||
const field = union_obj.fields.values()[field_index];
|
||||
const ptr_field_ty = try Module.simplePtrTypeWithAddressSpace(
|
||||
const ptr_field_ty = try Module.simplePtrType(
|
||||
arena,
|
||||
field.ty,
|
||||
union_ptr_ty.ptrIsMutable(),
|
||||
|
|
@ -9075,7 +9109,7 @@ fn elemPtrArray(
|
|||
) CompileError!Air.Inst.Ref {
|
||||
const array_ptr_ty = sema.typeOf(array_ptr);
|
||||
const pointee_type = array_ptr_ty.elemType().elemType();
|
||||
const result_ty = try Module.simplePtrTypeWithAddressSpace(
|
||||
const result_ty = try Module.simplePtrType(
|
||||
sema.arena,
|
||||
pointee_type,
|
||||
array_ptr_ty.ptrIsMutable(),
|
||||
|
|
@ -9581,11 +9615,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.simplePtrTypeWithAddressSpace(sema.arena, decl_tv.ty, variable.is_mutable, .One, decl.@"addrspace");
|
||||
const ty = try Module.simplePtrType(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.simplePtrTypeWithAddressSpace(sema.arena, decl_tv.ty, false, .One, decl.@"addrspace"),
|
||||
try Module.simplePtrType(sema.arena, decl_tv.ty, false, .One, decl.@"addrspace"),
|
||||
try Value.Tag.decl_ref.create(sema.arena, decl),
|
||||
);
|
||||
}
|
||||
|
|
@ -9608,8 +9642,9 @@ fn analyzeRef(
|
|||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src);
|
||||
const ptr_type = try Module.simplePtrType(sema.arena, operand_ty, false, .One);
|
||||
const mut_ptr_type = try Module.simplePtrType(sema.arena, operand_ty, true, .One);
|
||||
const address_space = target_util.defaultAddressSpace(sema.mod.getTarget(), .local);
|
||||
const ptr_type = try Module.simplePtrType(sema.arena, operand_ty, false, .One, address_space);
|
||||
const mut_ptr_type = try Module.simplePtrType(sema.arena, operand_ty, true, .One, address_space);
|
||||
const alloc = try block.addTy(.alloc, mut_ptr_type);
|
||||
try sema.storePtr(block, src, alloc, operand);
|
||||
|
||||
|
|
@ -10955,7 +10990,13 @@ fn analyzeComptimeAlloc(
|
|||
block: *Scope.Block,
|
||||
var_type: Type,
|
||||
) CompileError!Air.Inst.Ref {
|
||||
const ptr_type = try Module.simplePtrType(sema.arena, var_type, true, .One);
|
||||
const ptr_type = try Module.simplePtrType(
|
||||
sema.arena,
|
||||
var_type,
|
||||
true,
|
||||
.One,
|
||||
target_util.defaultAddressSpace(sema.mod.getTarget(), .global_constant),
|
||||
);
|
||||
|
||||
var anon_decl = try block.startAnonDecl();
|
||||
defer anon_decl.deinit();
|
||||
|
|
|
|||
15
src/Zir.zig
15
src/Zir.zig
|
|
@ -2309,7 +2309,6 @@ pub const Inst = struct {
|
|||
/// 0. lib_name: u32, // null terminated string index, if has_lib_name is set
|
||||
/// 1. cc: Ref, // if has_cc is set
|
||||
/// 2. align: Ref, // if has_align is set
|
||||
/// 3. addrspace: Ref, // if has_addrspace is set
|
||||
/// 3. return_type: Index // for each ret_body_len
|
||||
/// 4. body: Index // for each body_len
|
||||
/// 5. src_locs: Func.SrcLocs // if body_len != 0
|
||||
|
|
@ -2327,10 +2326,9 @@ pub const Inst = struct {
|
|||
has_lib_name: bool,
|
||||
has_cc: bool,
|
||||
has_align: bool,
|
||||
has_addrspace: bool,
|
||||
is_test: bool,
|
||||
is_extern: bool,
|
||||
_: u8 = undefined,
|
||||
_: u9 = undefined,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -4483,7 +4481,6 @@ const Writer = struct {
|
|||
false,
|
||||
.none,
|
||||
.none,
|
||||
.none,
|
||||
body,
|
||||
src,
|
||||
src_locs,
|
||||
|
|
@ -4512,11 +4509,6 @@ const Writer = struct {
|
|||
extra_index += 1;
|
||||
break :blk align_inst;
|
||||
};
|
||||
const addrspace_inst: Inst.Ref = if (!small.has_addrspace) .none else blk: {
|
||||
const addrspace_inst = @intToEnum(Zir.Inst.Ref, self.code.extra[extra_index]);
|
||||
extra_index += 1;
|
||||
break :blk addrspace_inst;
|
||||
};
|
||||
|
||||
const ret_ty_body = self.code.extra[extra_index..][0..extra.data.ret_body_len];
|
||||
extra_index += ret_ty_body.len;
|
||||
|
|
@ -4536,7 +4528,6 @@ const Writer = struct {
|
|||
small.is_extern,
|
||||
cc,
|
||||
align_inst,
|
||||
addrspace_inst,
|
||||
body,
|
||||
src,
|
||||
src_locs,
|
||||
|
|
@ -4619,7 +4610,6 @@ const Writer = struct {
|
|||
is_extern: bool,
|
||||
cc: Inst.Ref,
|
||||
align_inst: Inst.Ref,
|
||||
addrspace_inst: Inst.Ref,
|
||||
body: []const Inst.Index,
|
||||
src: LazySrcLoc,
|
||||
src_locs: Zir.Inst.Func.SrcLocs,
|
||||
|
|
@ -4637,7 +4627,6 @@ const Writer = struct {
|
|||
|
||||
try self.writeOptionalInstRef(stream, ", cc=", cc);
|
||||
try self.writeOptionalInstRef(stream, ", align=", align_inst);
|
||||
try self.writeOptionalInstRef(stream, ", addrspace=", addrspace_inst);
|
||||
try self.writeFlag(stream, ", vargs", var_args);
|
||||
try self.writeFlag(stream, ", extern", is_extern);
|
||||
try self.writeFlag(stream, ", inferror", inferred_error_set);
|
||||
|
|
@ -4915,7 +4904,6 @@ fn findDeclsInner(
|
|||
extra_index += @boolToInt(small.has_lib_name);
|
||||
extra_index += @boolToInt(small.has_cc);
|
||||
extra_index += @boolToInt(small.has_align);
|
||||
extra_index += @boolToInt(small.has_addrspace);
|
||||
const body = zir.extra[extra_index..][0..extra.data.body_len];
|
||||
return zir.findDeclsBody(list, body);
|
||||
},
|
||||
|
|
@ -5119,7 +5107,6 @@ pub fn getFnInfo(zir: Zir, fn_inst: Inst.Index) FnInfo {
|
|||
extra_index += @boolToInt(small.has_lib_name);
|
||||
extra_index += @boolToInt(small.has_cc);
|
||||
extra_index += @boolToInt(small.has_align);
|
||||
extra_index += @boolToInt(small.has_addrspace);
|
||||
const ret_ty_body = zir.extra[extra_index..][0..extra.data.ret_body_len];
|
||||
extra_index += ret_ty_body.len;
|
||||
const body = zir.extra[extra_index..][0..extra.data.body_len];
|
||||
|
|
|
|||
|
|
@ -700,7 +700,8 @@ pub const DeclGen = struct {
|
|||
@intCast(c_uint, llvm_params.len),
|
||||
llvm.Bool.fromBool(is_var_args),
|
||||
);
|
||||
const llvm_addrspace = self.llvmAddressSpace(t.fnAddressSpace());
|
||||
// TODO make .Fn not both a pointer type and a prototype
|
||||
const llvm_addrspace = self.llvmAddressSpace(.generic);
|
||||
return llvm_fn_ty.pointerType(llvm_addrspace);
|
||||
},
|
||||
.ComptimeInt => unreachable,
|
||||
|
|
|
|||
|
|
@ -18483,35 +18483,30 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
|
|||
fields[1]->special = ConstValSpecialStatic;
|
||||
fields[1]->type = ira->codegen->builtin_types.entry_num_lit_int;
|
||||
bigint_init_unsigned(&fields[1]->data.x_bigint, get_ptr_align(ira->codegen, type_entry));
|
||||
// address_space: AddressSpace
|
||||
ensure_field_index(result->type, "address_space", 2);
|
||||
fields[2]->special = ConstValSpecialStatic;
|
||||
fields[2]->type = get_builtin_type(ira->codegen, "AddressSpace");
|
||||
bigint_init_unsigned(&fields[2]->data.x_enum_tag, AddressSpaceGeneric);
|
||||
// is_generic: bool
|
||||
ensure_field_index(result->type, "is_generic", 3);
|
||||
ensure_field_index(result->type, "is_generic", 2);
|
||||
bool is_generic = type_entry->data.fn.is_generic;
|
||||
fields[2]->special = ConstValSpecialStatic;
|
||||
fields[2]->type = ira->codegen->builtin_types.entry_bool;
|
||||
fields[2]->data.x_bool = is_generic;
|
||||
// is_varargs: bool
|
||||
ensure_field_index(result->type, "is_var_args", 3);
|
||||
bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args;
|
||||
fields[3]->special = ConstValSpecialStatic;
|
||||
fields[3]->type = ira->codegen->builtin_types.entry_bool;
|
||||
fields[3]->data.x_bool = is_generic;
|
||||
// is_varargs: bool
|
||||
ensure_field_index(result->type, "is_var_args", 4);
|
||||
bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args;
|
||||
fields[4]->special = ConstValSpecialStatic;
|
||||
fields[4]->type = ira->codegen->builtin_types.entry_bool;
|
||||
fields[4]->data.x_bool = is_varargs;
|
||||
fields[3]->data.x_bool = is_varargs;
|
||||
// return_type: ?type
|
||||
ensure_field_index(result->type, "return_type", 5);
|
||||
fields[5]->special = ConstValSpecialStatic;
|
||||
fields[5]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
|
||||
ensure_field_index(result->type, "return_type", 4);
|
||||
fields[4]->special = ConstValSpecialStatic;
|
||||
fields[4]->type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type);
|
||||
if (type_entry->data.fn.fn_type_id.return_type == nullptr)
|
||||
fields[5]->data.x_optional = nullptr;
|
||||
fields[4]->data.x_optional = nullptr;
|
||||
else {
|
||||
ZigValue *return_type = ira->codegen->pass1_arena->create<ZigValue>();
|
||||
return_type->special = ConstValSpecialStatic;
|
||||
return_type->type = ira->codegen->builtin_types.entry_type;
|
||||
return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type;
|
||||
fields[5]->data.x_optional = return_type;
|
||||
fields[4]->data.x_optional = return_type;
|
||||
}
|
||||
// args: []TypeInfo.FnArg
|
||||
ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr);
|
||||
|
|
@ -18526,7 +18521,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, Scope *scope, AstNode *sour
|
|||
fn_arg_array->data.x_array.special = ConstArraySpecialNone;
|
||||
fn_arg_array->data.x_array.data.s_none.elements = ira->codegen->pass1_arena->allocate<ZigValue>(fn_arg_count);
|
||||
|
||||
init_const_slice(ira->codegen, fields[6], fn_arg_array, 0, fn_arg_count, false, nullptr);
|
||||
init_const_slice(ira->codegen, fields[5], fn_arg_array, 0, fn_arg_count, false, nullptr);
|
||||
|
||||
for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) {
|
||||
FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index];
|
||||
|
|
@ -19330,22 +19325,9 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
|
|||
if (alignment == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
|
||||
ZigValue *as_value = get_const_field(ira, source_node, payload, "address_space", 2);
|
||||
if (as_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
assert(as_value->special == ConstValSpecialStatic);
|
||||
assert(as_value->type == get_builtin_type(ira->codegen, "AddressSpace"));
|
||||
AddressSpace as = (AddressSpace)bigint_as_u32(&as_value->data.x_enum_tag);
|
||||
if (as != AddressSpaceGeneric) {
|
||||
ir_add_error_node(ira, source_node, buf_sprintf(
|
||||
"address space '%s' not available in stage 1 compiler, must be .generic",
|
||||
address_space_name(as)));
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
}
|
||||
|
||||
Error err;
|
||||
bool is_generic;
|
||||
if ((err = get_const_field_bool(ira, source_node, payload, "is_generic", 3, &is_generic)))
|
||||
if ((err = get_const_field_bool(ira, source_node, payload, "is_generic", 2, &is_generic)))
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
if (is_generic) {
|
||||
ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.Fn.is_generic must be false for @Type"));
|
||||
|
|
@ -19353,20 +19335,20 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
|
|||
}
|
||||
|
||||
bool is_var_args;
|
||||
if ((err = get_const_field_bool(ira, source_node, payload, "is_var_args", 4, &is_var_args)))
|
||||
if ((err = get_const_field_bool(ira, source_node, payload, "is_var_args", 3, &is_var_args)))
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
if (is_var_args && cc != CallingConventionC) {
|
||||
ir_add_error_node(ira, source_node, buf_sprintf("varargs functions must have C calling convention"));
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
}
|
||||
|
||||
ZigType *return_type = get_const_field_meta_type_optional(ira, source_node, payload, "return_type", 5);
|
||||
ZigType *return_type = get_const_field_meta_type_optional(ira, source_node, payload, "return_type", 4);
|
||||
if (return_type == nullptr) {
|
||||
ir_add_error_node(ira, source_node, buf_sprintf("TypeInfo.Fn.return_type must be non-null for @Type"));
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
}
|
||||
|
||||
ZigValue *args_value = get_const_field(ira, source_node, payload, "args", 6);
|
||||
ZigValue *args_value = get_const_field(ira, source_node, payload, "args", 5);
|
||||
if (args_value == nullptr)
|
||||
return ira->codegen->invalid_inst_gen->value->type;
|
||||
assert(args_value->special == ConstValSpecialStatic);
|
||||
|
|
|
|||
|
|
@ -544,3 +544,21 @@ pub fn largestAtomicBits(target: std.Target) u32 {
|
|||
.x86_64 => 128,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn defaultAddressSpace(
|
||||
target: std.Target,
|
||||
context: enum {
|
||||
/// Query the default address space for global constant values.
|
||||
global_constant,
|
||||
/// Query the default address space for global mutable values.
|
||||
global_mutable,
|
||||
/// Query the default address space for function-local values.
|
||||
local,
|
||||
/// Query the default address space for functions themselves.
|
||||
function,
|
||||
},
|
||||
) std.builtin.AddressSpace {
|
||||
_ = target;
|
||||
_ = context;
|
||||
return .generic;
|
||||
}
|
||||
|
|
|
|||
23
src/type.zig
23
src/type.zig
|
|
@ -530,8 +530,6 @@ pub const Type = extern union {
|
|||
return false;
|
||||
if (a.fnCallingConvention() != b.fnCallingConvention())
|
||||
return false;
|
||||
if (a.fnAddressSpace() != b.fnAddressSpace())
|
||||
return false;
|
||||
const a_param_len = a.fnParamLen();
|
||||
const b_param_len = b.fnParamLen();
|
||||
if (a_param_len != b_param_len)
|
||||
|
|
@ -838,7 +836,6 @@ pub const Type = extern union {
|
|||
.return_type = try payload.return_type.copy(allocator),
|
||||
.param_types = param_types,
|
||||
.cc = payload.cc,
|
||||
.@"addrspace" = payload.@"addrspace",
|
||||
.is_var_args = payload.is_var_args,
|
||||
.is_generic = payload.is_generic,
|
||||
.comptime_params = comptime_params.ptr,
|
||||
|
|
@ -1001,9 +998,6 @@ pub const Type = extern union {
|
|||
try writer.writeAll(") callconv(.");
|
||||
try writer.writeAll(@tagName(payload.cc));
|
||||
try writer.writeAll(") ");
|
||||
if (payload.@"addrspace" != .generic) {
|
||||
try writer.print("addrspace(.{s}) ", .{@tagName(payload.@"addrspace")});
|
||||
}
|
||||
ty = payload.return_type;
|
||||
continue;
|
||||
},
|
||||
|
|
@ -2730,18 +2724,6 @@ pub const Type = extern union {
|
|||
};
|
||||
}
|
||||
|
||||
pub fn fnAddressSpace(self: Type) std.builtin.AddressSpace {
|
||||
return switch (self.tag()) {
|
||||
.fn_noreturn_no_args => .generic,
|
||||
.fn_void_no_args => .generic,
|
||||
.fn_naked_noreturn_no_args => .generic,
|
||||
.fn_ccc_void_no_args => .generic,
|
||||
.function => self.castTag(.function).?.data.@"addrspace",
|
||||
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn fnInfo(ty: Type) Payload.Function.Data {
|
||||
return switch (ty.tag()) {
|
||||
.fn_noreturn_no_args => .{
|
||||
|
|
@ -2749,7 +2731,6 @@ pub const Type = extern union {
|
|||
.comptime_params = undefined,
|
||||
.return_type = initTag(.noreturn),
|
||||
.cc = .Unspecified,
|
||||
.@"addrspace" = .generic,
|
||||
.is_var_args = false,
|
||||
.is_generic = false,
|
||||
},
|
||||
|
|
@ -2758,7 +2739,6 @@ pub const Type = extern union {
|
|||
.comptime_params = undefined,
|
||||
.return_type = initTag(.void),
|
||||
.cc = .Unspecified,
|
||||
.@"addrspace" = .generic,
|
||||
.is_var_args = false,
|
||||
.is_generic = false,
|
||||
},
|
||||
|
|
@ -2767,7 +2747,6 @@ pub const Type = extern union {
|
|||
.comptime_params = undefined,
|
||||
.return_type = initTag(.noreturn),
|
||||
.cc = .Naked,
|
||||
.@"addrspace" = .generic,
|
||||
.is_var_args = false,
|
||||
.is_generic = false,
|
||||
},
|
||||
|
|
@ -2776,7 +2755,6 @@ pub const Type = extern union {
|
|||
.comptime_params = undefined,
|
||||
.return_type = initTag(.void),
|
||||
.cc = .C,
|
||||
.@"addrspace" = .generic,
|
||||
.is_var_args = false,
|
||||
.is_generic = false,
|
||||
},
|
||||
|
|
@ -3648,7 +3626,6 @@ pub const Type = extern union {
|
|||
comptime_params: [*]bool,
|
||||
return_type: Type,
|
||||
cc: std.builtin.CallingConvention,
|
||||
@"addrspace": std.builtin.AddressSpace,
|
||||
is_var_args: bool,
|
||||
is_generic: bool,
|
||||
|
||||
|
|
|
|||
|
|
@ -410,7 +410,6 @@ pub fn addCases(ctx: *TestContext) !void {
|
|||
\\ .Fn = .{
|
||||
\\ .calling_convention = .Unspecified,
|
||||
\\ .alignment = 0,
|
||||
\\ .address_space = .generic,
|
||||
\\ .is_generic = true,
|
||||
\\ .is_var_args = false,
|
||||
\\ .return_type = u0,
|
||||
|
|
@ -427,7 +426,6 @@ pub fn addCases(ctx: *TestContext) !void {
|
|||
\\ .Fn = .{
|
||||
\\ .calling_convention = .Unspecified,
|
||||
\\ .alignment = 0,
|
||||
\\ .address_space = .generic,
|
||||
\\ .is_generic = false,
|
||||
\\ .is_var_args = true,
|
||||
\\ .return_type = u0,
|
||||
|
|
@ -444,7 +442,6 @@ pub fn addCases(ctx: *TestContext) !void {
|
|||
\\ .Fn = .{
|
||||
\\ .calling_convention = .Unspecified,
|
||||
\\ .alignment = 0,
|
||||
\\ .address_space = .generic,
|
||||
\\ .is_generic = false,
|
||||
\\ .is_var_args = false,
|
||||
\\ .return_type = null,
|
||||
|
|
@ -456,23 +453,6 @@ pub fn addCases(ctx: *TestContext) !void {
|
|||
"tmp.zig:1:20: error: TypeInfo.Fn.return_type must be non-null for @Type",
|
||||
});
|
||||
|
||||
ctx.objErrStage1("@Type(.Fn) with invalid address space ",
|
||||
\\const Foo = @Type(.{
|
||||
\\ .Fn = .{
|
||||
\\ .calling_convention = .Unspecified,
|
||||
\\ .alignment = 0,
|
||||
\\ .address_space = .fs,
|
||||
\\ .is_generic = false,
|
||||
\\ .is_var_args = false,
|
||||
\\ .return_type = u0,
|
||||
\\ .args = &[_]@import("std").builtin.TypeInfo.FnArg{},
|
||||
\\ },
|
||||
\\});
|
||||
\\comptime { _ = Foo; }
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:1:20: error: address space 'fs' not available in stage 1 compiler, must be .generic",
|
||||
});
|
||||
|
||||
ctx.objErrStage1("@Type for union with opaque field",
|
||||
\\const TypeInfo = @import("std").builtin.TypeInfo;
|
||||
\\const Untagged = @Type(.{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue