authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-09-02 14:46:31+02:00
committergravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-09-20 02:29:03+02:00
log805e1bffbdcab84717356fb1a7b375369407d9c2
treee6d3eb330017cea8e54eda7171ed75777e3088a0
parent7da9fa6fe2e982d10ebc9c3844d1249a4eb1d514

Address Spaces: Sema basics


5 files changed, 108 insertions(+), 20 deletions(-)

lib/std/builtin.zig+1
...@@ -170,6 +170,7 @@ pub const CallingConvention = enum {...@@ -170,6 +170,7 @@ pub const CallingConvention = enum {
170/// therefore must be kept in sync with the compiler implementation.170/// therefore must be kept in sync with the compiler implementation.
171pub const AddressSpace = enum {171pub const AddressSpace = enum {
172 generic,172 generic,
173 special,
173};174};
174175
175/// This data structure is used by the Zig language code generation and176/// This data structure is used by the Zig language code generation and
src/AstGen.zig+2-2
...@@ -3134,7 +3134,7 @@ fn fnDecl(...@@ -3134,7 +3134,7 @@ fn fnDecl(
3134 _ = try decl_gz.addBreak(.break_inline, block_inst, func_inst);3134 _ = try decl_gz.addBreak(.break_inline, block_inst, func_inst);
3135 try decl_gz.setBlockBody(block_inst);3135 try decl_gz.setBlockBody(block_inst);
31363136
3137 try wip_decls.payload.ensureUnusedCapacity(gpa, 9);3137 try wip_decls.payload.ensureUnusedCapacity(gpa, 10);
3138 {3138 {
3139 const contents_hash = std.zig.hashSrc(tree.getNodeSource(decl_node));3139 const contents_hash = std.zig.hashSrc(tree.getNodeSource(decl_node));
3140 const casted = @bitCast([4]u32, contents_hash);3140 const casted = @bitCast([4]u32, contents_hash);
...@@ -3284,7 +3284,7 @@ fn globalVarDecl(...@@ -3284,7 +3284,7 @@ fn globalVarDecl(
3284 _ = try block_scope.addBreak(.break_inline, block_inst, var_inst);3284 _ = try block_scope.addBreak(.break_inline, block_inst, var_inst);
3285 try block_scope.setBlockBody(block_inst);3285 try block_scope.setBlockBody(block_inst);
32863286
3287 try wip_decls.payload.ensureUnusedCapacity(gpa, 9);3287 try wip_decls.payload.ensureUnusedCapacity(gpa, 10);
3288 {3288 {
3289 const contents_hash = std.zig.hashSrc(tree.getNodeSource(node));3289 const contents_hash = std.zig.hashSrc(tree.getNodeSource(node));
3290 const casted = @bitCast([4]u32, contents_hash);3290 const casted = @bitCast([4]u32, contents_hash);
src/Module.zig+37-16
...@@ -288,6 +288,8 @@ pub const Decl = struct {...@@ -288,6 +288,8 @@ pub const Decl = struct {
288 align_val: Value,288 align_val: Value,
289 /// Populated when `has_tv`.289 /// Populated when `has_tv`.
290 linksection_val: Value,290 linksection_val: Value,
291 /// Populated when `has_tv`.
292 @"addrspace": std.builtin.AddressSpace,
291 /// The memory for ty, val, align_val, linksection_val.293 /// The memory for ty, val, align_val, linksection_val.
292 /// If this is `null` then there is no memory management needed.294 /// If this is `null` then there is no memory management needed.
293 value_arena: ?*std.heap.ArenaAllocator.State = null,295 value_arena: ?*std.heap.ArenaAllocator.State = null,
...@@ -351,7 +353,7 @@ pub const Decl = struct {...@@ -351,7 +353,7 @@ pub const Decl = struct {
351 /// to require re-analysis.353 /// to require re-analysis.
352 outdated,354 outdated,
353 },355 },
354 /// Whether `typed_value`, `align_val`, and `linksection_val` are populated.356 /// Whether `typed_value`, `align_val`, `linksection_val` and `has_addrspace` are populated.
355 has_tv: bool,357 has_tv: bool,
356 /// If `true` it means the `Decl` is the resource owner of the type/value associated358 /// If `true` it means the `Decl` is the resource owner of the type/value associated
357 /// with it. That means when `Decl` is destroyed, the cleanup code should additionally359 /// with it. That means when `Decl` is destroyed, the cleanup code should additionally
...@@ -366,8 +368,8 @@ pub const Decl = struct {...@@ -366,8 +368,8 @@ pub const Decl = struct {
366 is_exported: bool,368 is_exported: bool,
367 /// Whether the ZIR code provides an align instruction.369 /// Whether the ZIR code provides an align instruction.
368 has_align: bool,370 has_align: bool,
369 /// Whether the ZIR code provides a linksection instruction.371 /// Whether the ZIR code provides a linksection and address space instruction.
370 has_linksection: bool,372 has_linksection_or_addrspace: bool,
371 /// Flag used by garbage collection to mark and sweep.373 /// Flag used by garbage collection to mark and sweep.
372 /// Decls which correspond to an AST node always have this field set to `true`.374 /// Decls which correspond to an AST node always have this field set to `true`.
373 /// Anonymous Decls are initialized with this field set to `false` and then it375 /// Anonymous Decls are initialized with this field set to `false` and then it
...@@ -489,14 +491,22 @@ pub const Decl = struct {...@@ -489,14 +491,22 @@ pub const Decl = struct {
489 if (!decl.has_align) return .none;491 if (!decl.has_align) return .none;
490 assert(decl.zir_decl_index != 0);492 assert(decl.zir_decl_index != 0);
491 const zir = decl.namespace.file_scope.zir;493 const zir = decl.namespace.file_scope.zir;
492 return @intToEnum(Zir.Inst.Ref, zir.extra[decl.zir_decl_index + 6]);494 return @intToEnum(Zir.Inst.Ref, zir.extra[decl.zir_decl_index + 7]);
493 }495 }
494496
495 pub fn zirLinksectionRef(decl: Decl) Zir.Inst.Ref {497 pub fn zirLinksectionRef(decl: Decl) Zir.Inst.Ref {
496 if (!decl.has_linksection) return .none;498 if (!decl.has_linksection_or_addrspace) return .none;
497 assert(decl.zir_decl_index != 0);499 assert(decl.zir_decl_index != 0);
498 const zir = decl.namespace.file_scope.zir;500 const zir = decl.namespace.file_scope.zir;
499 const extra_index = decl.zir_decl_index + 6 + @boolToInt(decl.has_align);501 const extra_index = decl.zir_decl_index + 7 + @boolToInt(decl.has_align);
502 return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
503 }
504
505 pub fn zirAddrspaceRef(decl: Decl) Zir.Inst.Ref {
506 if (!decl.has_linksection_or_addrspace) return .none;
507 assert(decl.zir_decl_index != 0);
508 const zir = decl.namespace.file_scope.zir;
509 const extra_index = decl.zir_decl_index + 7 + @boolToInt(decl.has_align) + 1;
500 return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);510 return @intToEnum(Zir.Inst.Ref, zir.extra[extra_index]);
501 }511 }
502512
...@@ -3072,7 +3082,7 @@ pub fn semaFile(mod: *Module, file: *Scope.File) SemaError!void {...@@ -3072,7 +3082,7 @@ pub fn semaFile(mod: *Module, file: *Scope.File) SemaError!void {
3072 new_decl.is_pub = true;3082 new_decl.is_pub = true;
3073 new_decl.is_exported = false;3083 new_decl.is_exported = false;
3074 new_decl.has_align = false;3084 new_decl.has_align = false;
3075 new_decl.has_linksection = false;3085 new_decl.has_linksection_or_addrspace = false;
3076 new_decl.ty = struct_ty;3086 new_decl.ty = struct_ty;
3077 new_decl.val = struct_val;3087 new_decl.val = struct_val;
3078 new_decl.has_tv = true;3088 new_decl.has_tv = true;
...@@ -3202,6 +3212,12 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3202,6 +3212,12 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3202 if (linksection_ref == .none) break :blk Value.initTag(.null_value);3212 if (linksection_ref == .none) break :blk Value.initTag(.null_value);
3203 break :blk (try sema.resolveInstConst(&block_scope, src, linksection_ref)).val;3213 break :blk (try sema.resolveInstConst(&block_scope, src, linksection_ref)).val;
3204 };3214 };
3215 const address_space = blk: {
3216 const addrspace_ref = decl.zirAddrspaceRef();
3217 if (addrspace_ref == .none) break :blk .generic;
3218 const addrspace_tv = try sema.resolveInstConst(&block_scope, src, addrspace_ref);
3219 break :blk addrspace_tv.val.toEnum(std.builtin.AddressSpace);
3220 };
3205 // Note this resolves the type of the Decl, not the value; if this Decl3221 // Note this resolves the type of the Decl, not the value; if this Decl
3206 // is a struct, for example, this resolves `type` (which needs no resolution),3222 // is a struct, for example, this resolves `type` (which needs no resolution),
3207 // not the struct itself.3223 // not the struct itself.
...@@ -3258,6 +3274,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3258,6 +3274,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3258 decl.val = try decl_tv.val.copy(&decl_arena.allocator);3274 decl.val = try decl_tv.val.copy(&decl_arena.allocator);
3259 decl.align_val = try align_val.copy(&decl_arena.allocator);3275 decl.align_val = try align_val.copy(&decl_arena.allocator);
3260 decl.linksection_val = try linksection_val.copy(&decl_arena.allocator);3276 decl.linksection_val = try linksection_val.copy(&decl_arena.allocator);
3277 decl.@"addrspace" = address_space;
3261 decl.has_tv = true;3278 decl.has_tv = true;
3262 decl.owns_tv = owns_tv;3279 decl.owns_tv = owns_tv;
3263 decl_arena_state.* = decl_arena.state;3280 decl_arena_state.* = decl_arena.state;
...@@ -3319,6 +3336,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {...@@ -3319,6 +3336,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
3319 decl.val = try decl_tv.val.copy(&decl_arena.allocator);3336 decl.val = try decl_tv.val.copy(&decl_arena.allocator);
3320 decl.align_val = try align_val.copy(&decl_arena.allocator);3337 decl.align_val = try align_val.copy(&decl_arena.allocator);
3321 decl.linksection_val = try linksection_val.copy(&decl_arena.allocator);3338 decl.linksection_val = try linksection_val.copy(&decl_arena.allocator);
3339 decl.@"addrspace" = address_space;
3322 decl.has_tv = true;3340 decl.has_tv = true;
3323 decl_arena_state.* = decl_arena.state;3341 decl_arena_state.* = decl_arena.state;
3324 decl.value_arena = decl_arena_state;3342 decl.value_arena = decl_arena_state;
...@@ -3526,8 +3544,8 @@ pub fn scanNamespace(...@@ -3526,8 +3544,8 @@ pub fn scanNamespace(
35263544
3527 const decl_sub_index = extra_index;3545 const decl_sub_index = extra_index;
3528 extra_index += 7; // src_hash(4) + line(1) + name(1) + value(1)3546 extra_index += 7; // src_hash(4) + line(1) + name(1) + value(1)
3529 extra_index += @truncate(u1, flags >> 2);3547 extra_index += @truncate(u1, flags >> 2); // Align
3530 extra_index += @truncate(u1, flags >> 3);3548 extra_index += @as(u2, @truncate(u1, flags >> 3)) * 2; // Link section or address space, consists of 2 Refs
35313549
3532 try scanDecl(&scan_decl_iter, decl_sub_index, flags);3550 try scanDecl(&scan_decl_iter, decl_sub_index, flags);
3533 }3551 }
...@@ -3553,10 +3571,10 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -3553,10 +3571,10 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
3553 const zir = namespace.file_scope.zir;3571 const zir = namespace.file_scope.zir;
35543572
3555 // zig fmt: off3573 // zig fmt: off
3556 const is_pub = (flags & 0b0001) != 0;3574 const is_pub = (flags & 0b0001) != 0;
3557 const export_bit = (flags & 0b0010) != 0;3575 const export_bit = (flags & 0b0010) != 0;
3558 const has_align = (flags & 0b0100) != 0;3576 const has_align = (flags & 0b0100) != 0;
3559 const has_linksection = (flags & 0b1000) != 0;3577 const has_linksection_or_addrspace = (flags & 0b1000) != 0;
3560 // zig fmt: on3578 // zig fmt: on
35613579
3562 const line = iter.parent_decl.relativeToLine(zir.extra[decl_sub_index + 4]);3580 const line = iter.parent_decl.relativeToLine(zir.extra[decl_sub_index + 4]);
...@@ -3639,7 +3657,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -3639,7 +3657,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
3639 new_decl.is_exported = is_exported;3657 new_decl.is_exported = is_exported;
3640 new_decl.is_usingnamespace = is_usingnamespace;3658 new_decl.is_usingnamespace = is_usingnamespace;
3641 new_decl.has_align = has_align;3659 new_decl.has_align = has_align;
3642 new_decl.has_linksection = has_linksection;3660 new_decl.has_linksection_or_addrspace = has_linksection_or_addrspace;
3643 new_decl.zir_decl_index = @intCast(u32, decl_sub_index);3661 new_decl.zir_decl_index = @intCast(u32, decl_sub_index);
3644 new_decl.alive = true; // This Decl corresponds to an AST node and therefore always alive.3662 new_decl.alive = true; // This Decl corresponds to an AST node and therefore always alive.
3645 return;3663 return;
...@@ -3656,7 +3674,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi...@@ -3656,7 +3674,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
3656 decl.is_exported = is_exported;3674 decl.is_exported = is_exported;
3657 decl.is_usingnamespace = is_usingnamespace;3675 decl.is_usingnamespace = is_usingnamespace;
3658 decl.has_align = has_align;3676 decl.has_align = has_align;
3659 decl.has_linksection = has_linksection;3677 decl.has_linksection_or_addrspace = has_linksection_or_addrspace;
3660 decl.zir_decl_index = @intCast(u32, decl_sub_index);3678 decl.zir_decl_index = @intCast(u32, decl_sub_index);
3661 if (decl.getFunction()) |_| {3679 if (decl.getFunction()) |_| {
3662 switch (mod.comp.bin_file.tag) {3680 switch (mod.comp.bin_file.tag) {
...@@ -4028,6 +4046,7 @@ pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: Ast....@@ -4028,6 +4046,7 @@ pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: Ast.
4028 .val = undefined,4046 .val = undefined,
4029 .align_val = undefined,4047 .align_val = undefined,
4030 .linksection_val = undefined,4048 .linksection_val = undefined,
4049 .@"addrspace" = undefined,
4031 .analysis = .unreferenced,4050 .analysis = .unreferenced,
4032 .deletion_flag = false,4051 .deletion_flag = false,
4033 .zir_decl_index = 0,4052 .zir_decl_index = 0,
...@@ -4052,7 +4071,7 @@ pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: Ast....@@ -4052,7 +4071,7 @@ pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: Ast.
4052 .generation = 0,4071 .generation = 0,
4053 .is_pub = false,4072 .is_pub = false,
4054 .is_exported = false,4073 .is_exported = false,
4055 .has_linksection = false,4074 .has_linksection_or_addrspace = false,
4056 .has_align = false,4075 .has_align = false,
4057 .alive = false,4076 .alive = false,
4058 .is_usingnamespace = false,4077 .is_usingnamespace = false,
...@@ -4357,6 +4376,7 @@ pub fn ptrType(...@@ -4357,6 +4376,7 @@ pub fn ptrType(
4357 elem_ty: Type,4376 elem_ty: Type,
4358 sentinel: ?Value,4377 sentinel: ?Value,
4359 @"align": u32,4378 @"align": u32,
4379 @"addrspace": std.builtin.AddressSpace,
4360 bit_offset: u16,4380 bit_offset: u16,
4361 host_size: u16,4381 host_size: u16,
4362 mutable: bool,4382 mutable: bool,
...@@ -4371,6 +4391,7 @@ pub fn ptrType(...@@ -4371,6 +4391,7 @@ pub fn ptrType(
4371 .pointee_type = elem_ty,4391 .pointee_type = elem_ty,
4372 .sentinel = sentinel,4392 .sentinel = sentinel,
4373 .@"align" = @"align",4393 .@"align" = @"align",
4394 .@"addrspace" = @"addrspace",
4374 .bit_offset = bit_offset,4395 .bit_offset = bit_offset,
4375 .host_size = host_size,4396 .host_size = host_size,
4376 .@"allowzero" = @"allowzero",4397 .@"allowzero" = @"allowzero",
src/Sema.zig+26-2
...@@ -3004,7 +3004,7 @@ fn analyzeCall(...@@ -3004,7 +3004,7 @@ fn analyzeCall(
3004 new_decl.is_pub = module_fn.owner_decl.is_pub;3004 new_decl.is_pub = module_fn.owner_decl.is_pub;
3005 new_decl.is_exported = module_fn.owner_decl.is_exported;3005 new_decl.is_exported = module_fn.owner_decl.is_exported;
3006 new_decl.has_align = module_fn.owner_decl.has_align;3006 new_decl.has_align = module_fn.owner_decl.has_align;
3007 new_decl.has_linksection = module_fn.owner_decl.has_linksection;3007 new_decl.has_linksection_or_addrspace = module_fn.owner_decl.has_linksection_or_addrspace;
3008 new_decl.zir_decl_index = module_fn.owner_decl.zir_decl_index;3008 new_decl.zir_decl_index = module_fn.owner_decl.zir_decl_index;
3009 new_decl.alive = true; // This Decl is called at runtime.3009 new_decl.alive = true; // This Decl is called at runtime.
3010 new_decl.has_tv = true;3010 new_decl.has_tv = true;
...@@ -3895,6 +3895,7 @@ fn zirFunc(...@@ -3895,6 +3895,7 @@ fn zirFunc(
3895 ret_ty_body,3895 ret_ty_body,
3896 cc,3896 cc,
3897 Value.initTag(.null_value),3897 Value.initTag(.null_value),
3898 .generic,
3898 false,3899 false,
3899 inferred_error_set,3900 inferred_error_set,
3900 false,3901 false,
...@@ -3911,6 +3912,7 @@ fn funcCommon(...@@ -3911,6 +3912,7 @@ fn funcCommon(
3911 ret_ty_body: []const Zir.Inst.Index,3912 ret_ty_body: []const Zir.Inst.Index,
3912 cc: std.builtin.CallingConvention,3913 cc: std.builtin.CallingConvention,
3913 align_val: Value,3914 align_val: Value,
3915 address_space: std.builtin.AddressSpace,
3914 var_args: bool,3916 var_args: bool,
3915 inferred_error_set: bool,3917 inferred_error_set: bool,
3916 is_extern: bool,3918 is_extern: bool,
...@@ -3968,7 +3970,7 @@ fn funcCommon(...@@ -3968,7 +3970,7 @@ fn funcCommon(
3968 // Hot path for some common function types.3970 // Hot path for some common function types.
3969 // TODO can we eliminate some of these Type tag values? seems unnecessarily complicated.3971 // TODO can we eliminate some of these Type tag values? seems unnecessarily complicated.
3970 if (!is_generic and block.params.items.len == 0 and !var_args and3972 if (!is_generic and block.params.items.len == 0 and !var_args and
3971 align_val.tag() == .null_value and !inferred_error_set)3973 align_val.tag() == .null_value and !inferred_error_set and address_space == .generic)
3972 {3974 {
3973 if (bare_return_type.zigTypeTag() == .NoReturn and cc == .Unspecified) {3975 if (bare_return_type.zigTypeTag() == .NoReturn and cc == .Unspecified) {
3974 break :fn_ty Type.initTag(.fn_noreturn_no_args);3976 break :fn_ty Type.initTag(.fn_noreturn_no_args);
...@@ -4020,6 +4022,7 @@ fn funcCommon(...@@ -4020,6 +4022,7 @@ fn funcCommon(
4020 .comptime_params = comptime_params.ptr,4022 .comptime_params = comptime_params.ptr,
4021 .return_type = return_type,4023 .return_type = return_type,
4022 .cc = cc,4024 .cc = cc,
4025 .@"addrspace" = address_space,
4023 .is_var_args = var_args,4026 .is_var_args = var_args,
4024 .is_generic = is_generic,4027 .is_generic = is_generic,
4025 });4028 });
...@@ -6876,6 +6879,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp...@@ -6876,6 +6879,7 @@ fn zirPtrTypeSimple(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Comp
6876 elem_type,6879 elem_type,
6877 null,6880 null,
6878 0,6881 0,
6882 .generic,
6879 0,6883 0,
6880 0,6884 0,
6881 inst_data.is_mutable,6885 inst_data.is_mutable,
...@@ -6908,6 +6912,13 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr...@@ -6908,6 +6912,13 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
6908 break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u32);6912 break :blk try sema.resolveAlreadyCoercedInt(block, .unneeded, ref, u32);
6909 } else 0;6913 } else 0;
69106914
6915 const address_space = if (inst_data.flags.has_addrspace) blk: {
6916 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
6917 extra_i += 1;
6918 const addrspace_tv = try sema.resolveInstConst(block, .unneeded, ref);
6919 break :blk addrspace_tv.val.toEnum(std.builtin.AddressSpace);
6920 } else .generic;
6921
6911 const bit_start = if (inst_data.flags.has_bit_range) blk: {6922 const bit_start = if (inst_data.flags.has_bit_range) blk: {
6912 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);6923 const ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_i]);
6913 extra_i += 1;6924 extra_i += 1;
...@@ -6930,6 +6941,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr...@@ -6930,6 +6941,7 @@ fn zirPtrType(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
6930 elem_type,6941 elem_type,
6931 sentinel,6942 sentinel,
6932 abi_align,6943 abi_align,
6944 address_space,
6933 bit_start,6945 bit_start,
6934 bit_end,6946 bit_end,
6935 inst_data.flags.is_mutable,6947 inst_data.flags.is_mutable,
...@@ -8035,6 +8047,7 @@ fn zirFuncExtended(...@@ -8035,6 +8047,7 @@ fn zirFuncExtended(
8035 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };8047 const src: LazySrcLoc = .{ .node_offset = extra.data.src_node };
8036 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = extra.data.src_node };8048 const cc_src: LazySrcLoc = .{ .node_offset_fn_type_cc = extra.data.src_node };
8037 const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align8049 const align_src: LazySrcLoc = src; // TODO add a LazySrcLoc that points at align
8050 const addrspace_src: LazySrcLoc = src; // TODO(Snektron) add a LazySrcLoc that points at addrspace
8038 const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);8051 const small = @bitCast(Zir.Inst.ExtendedFunc.Small, extended.small);
80398052
8040 var extra_index: usize = extra.end;8053 var extra_index: usize = extra.end;
...@@ -8059,6 +8072,13 @@ fn zirFuncExtended(...@@ -8059,6 +8072,13 @@ fn zirFuncExtended(
8059 break :blk align_tv.val;8072 break :blk align_tv.val;
8060 } else Value.initTag(.null_value);8073 } else Value.initTag(.null_value);
80618074
8075 const address_space: std.builtin.AddressSpace = if (small.has_addrspace) blk: {
8076 const addrspace_ref = @intToEnum(Zir.Inst.Ref, sema.code.extra[extra_index]);
8077 extra_index += 1;
8078 const addrspace_tv = try sema.resolveInstConst(block, addrspace_src, addrspace_ref);
8079 break :blk addrspace_tv.val.toEnum(std.builtin.AddressSpace);
8080 } else .generic;
8081
8062 const ret_ty_body = sema.code.extra[extra_index..][0..extra.data.ret_body_len];8082 const ret_ty_body = sema.code.extra[extra_index..][0..extra.data.ret_body_len];
8063 extra_index += ret_ty_body.len;8083 extra_index += ret_ty_body.len;
80648084
...@@ -8081,6 +8101,7 @@ fn zirFuncExtended(...@@ -8081,6 +8101,7 @@ fn zirFuncExtended(
8081 ret_ty_body,8101 ret_ty_body,
8082 cc,8102 cc,
8083 align_val,8103 align_val,
8104 address_space,
8084 is_var_args,8105 is_var_args,
8085 is_inferred_error,8106 is_inferred_error,
8086 is_extern,8107 is_extern,
...@@ -9693,6 +9714,9 @@ fn analyzeSlice(...@@ -9693,6 +9714,9 @@ fn analyzeSlice(
9693 return_elem_type,9714 return_elem_type,
9694 if (end_opt == .none) slice_sentinel else null,9715 if (end_opt == .none) slice_sentinel else null,
9695 0, // TODO alignment9716 0, // TODO alignment
9717 // TODO(Snektron) address space, should be inferred from the pointer type.
9718 // TODO(Snektron) address space for slicing a local, should compute address space from context and architecture.
9719 .generic,
9696 0,9720 0,
9697 0,9721 0,
9698 !ptr_child.isConstPtr(),9722 !ptr_child.isConstPtr(),
src/type.zig+42
...@@ -289,6 +289,7 @@ pub const Type = extern union {...@@ -289,6 +289,7 @@ pub const Type = extern union {
289 .pointee_type = Type.initTag(.comptime_int),289 .pointee_type = Type.initTag(.comptime_int),
290 .sentinel = null,290 .sentinel = null,
291 .@"align" = 0,291 .@"align" = 0,
292 .@"addrspace" = .generic,
292 .bit_offset = 0,293 .bit_offset = 0,
293 .host_size = 0,294 .host_size = 0,
294 .@"allowzero" = false,295 .@"allowzero" = false,
...@@ -300,6 +301,7 @@ pub const Type = extern union {...@@ -300,6 +301,7 @@ pub const Type = extern union {
300 .pointee_type = Type.initTag(.u8),301 .pointee_type = Type.initTag(.u8),
301 .sentinel = null,302 .sentinel = null,
302 .@"align" = 0,303 .@"align" = 0,
304 .@"addrspace" = .generic,
303 .bit_offset = 0,305 .bit_offset = 0,
304 .host_size = 0,306 .host_size = 0,
305 .@"allowzero" = false,307 .@"allowzero" = false,
...@@ -311,6 +313,7 @@ pub const Type = extern union {...@@ -311,6 +313,7 @@ pub const Type = extern union {
311 .pointee_type = self.castPointer().?.data,313 .pointee_type = self.castPointer().?.data,
312 .sentinel = null,314 .sentinel = null,
313 .@"align" = 0,315 .@"align" = 0,
316 .@"addrspace" = .generic,
314 .bit_offset = 0,317 .bit_offset = 0,
315 .host_size = 0,318 .host_size = 0,
316 .@"allowzero" = false,319 .@"allowzero" = false,
...@@ -322,6 +325,7 @@ pub const Type = extern union {...@@ -322,6 +325,7 @@ pub const Type = extern union {
322 .pointee_type = self.castPointer().?.data,325 .pointee_type = self.castPointer().?.data,
323 .sentinel = null,326 .sentinel = null,
324 .@"align" = 0,327 .@"align" = 0,
328 .@"addrspace" = .generic,
325 .bit_offset = 0,329 .bit_offset = 0,
326 .host_size = 0,330 .host_size = 0,
327 .@"allowzero" = false,331 .@"allowzero" = false,
...@@ -333,6 +337,7 @@ pub const Type = extern union {...@@ -333,6 +337,7 @@ pub const Type = extern union {
333 .pointee_type = self.castPointer().?.data,337 .pointee_type = self.castPointer().?.data,
334 .sentinel = null,338 .sentinel = null,
335 .@"align" = 0,339 .@"align" = 0,
340 .@"addrspace" = .generic,
336 .bit_offset = 0,341 .bit_offset = 0,
337 .host_size = 0,342 .host_size = 0,
338 .@"allowzero" = false,343 .@"allowzero" = false,
...@@ -344,6 +349,7 @@ pub const Type = extern union {...@@ -344,6 +349,7 @@ pub const Type = extern union {
344 .pointee_type = Type.initTag(.u8),349 .pointee_type = Type.initTag(.u8),
345 .sentinel = null,350 .sentinel = null,
346 .@"align" = 0,351 .@"align" = 0,
352 .@"addrspace" = .generic,
347 .bit_offset = 0,353 .bit_offset = 0,
348 .host_size = 0,354 .host_size = 0,
349 .@"allowzero" = false,355 .@"allowzero" = false,
...@@ -355,6 +361,7 @@ pub const Type = extern union {...@@ -355,6 +361,7 @@ pub const Type = extern union {
355 .pointee_type = self.castPointer().?.data,361 .pointee_type = self.castPointer().?.data,
356 .sentinel = null,362 .sentinel = null,
357 .@"align" = 0,363 .@"align" = 0,
364 .@"addrspace" = .generic,
358 .bit_offset = 0,365 .bit_offset = 0,
359 .host_size = 0,366 .host_size = 0,
360 .@"allowzero" = false,367 .@"allowzero" = false,
...@@ -366,6 +373,7 @@ pub const Type = extern union {...@@ -366,6 +373,7 @@ pub const Type = extern union {
366 .pointee_type = Type.initTag(.u8),373 .pointee_type = Type.initTag(.u8),
367 .sentinel = null,374 .sentinel = null,
368 .@"align" = 0,375 .@"align" = 0,
376 .@"addrspace" = .generic,
369 .bit_offset = 0,377 .bit_offset = 0,
370 .host_size = 0,378 .host_size = 0,
371 .@"allowzero" = false,379 .@"allowzero" = false,
...@@ -377,6 +385,7 @@ pub const Type = extern union {...@@ -377,6 +385,7 @@ pub const Type = extern union {
377 .pointee_type = self.castPointer().?.data,385 .pointee_type = self.castPointer().?.data,
378 .sentinel = null,386 .sentinel = null,
379 .@"align" = 0,387 .@"align" = 0,
388 .@"addrspace" = .generic,
380 .bit_offset = 0,389 .bit_offset = 0,
381 .host_size = 0,390 .host_size = 0,
382 .@"allowzero" = false,391 .@"allowzero" = false,
...@@ -388,6 +397,7 @@ pub const Type = extern union {...@@ -388,6 +397,7 @@ pub const Type = extern union {
388 .pointee_type = self.castPointer().?.data,397 .pointee_type = self.castPointer().?.data,
389 .sentinel = null,398 .sentinel = null,
390 .@"align" = 0,399 .@"align" = 0,
400 .@"addrspace" = .generic,
391 .bit_offset = 0,401 .bit_offset = 0,
392 .host_size = 0,402 .host_size = 0,
393 .@"allowzero" = false,403 .@"allowzero" = false,
...@@ -399,6 +409,7 @@ pub const Type = extern union {...@@ -399,6 +409,7 @@ pub const Type = extern union {
399 .pointee_type = self.castPointer().?.data,409 .pointee_type = self.castPointer().?.data,
400 .sentinel = null,410 .sentinel = null,
401 .@"align" = 0,411 .@"align" = 0,
412 .@"addrspace" = .generic,
402 .bit_offset = 0,413 .bit_offset = 0,
403 .host_size = 0,414 .host_size = 0,
404 .@"allowzero" = false,415 .@"allowzero" = false,
...@@ -410,6 +421,7 @@ pub const Type = extern union {...@@ -410,6 +421,7 @@ pub const Type = extern union {
410 .pointee_type = self.castPointer().?.data,421 .pointee_type = self.castPointer().?.data,
411 .sentinel = null,422 .sentinel = null,
412 .@"align" = 0,423 .@"align" = 0,
424 .@"addrspace" = .generic,
413 .bit_offset = 0,425 .bit_offset = 0,
414 .host_size = 0,426 .host_size = 0,
415 .@"allowzero" = false,427 .@"allowzero" = false,
...@@ -462,6 +474,8 @@ pub const Type = extern union {...@@ -462,6 +474,8 @@ pub const Type = extern union {
462 return false;474 return false;
463 if (info_a.host_size != info_b.host_size)475 if (info_a.host_size != info_b.host_size)
464 return false;476 return false;
477 if (info_a.@"addrspace" != info_b.@"addrspace")
478 return false;
465479
466 const sentinel_a = info_a.sentinel;480 const sentinel_a = info_a.sentinel;
467 const sentinel_b = info_b.sentinel;481 const sentinel_b = info_b.sentinel;
...@@ -516,6 +530,8 @@ pub const Type = extern union {...@@ -516,6 +530,8 @@ pub const Type = extern union {
516 return false;530 return false;
517 if (a.fnCallingConvention() != b.fnCallingConvention())531 if (a.fnCallingConvention() != b.fnCallingConvention())
518 return false;532 return false;
533 if (a.fnAddressSpace() != b.fnAddressSpace())
534 return false;
519 const a_param_len = a.fnParamLen();535 const a_param_len = a.fnParamLen();
520 const b_param_len = b.fnParamLen();536 const b_param_len = b.fnParamLen();
521 if (a_param_len != b_param_len)537 if (a_param_len != b_param_len)
...@@ -822,6 +838,7 @@ pub const Type = extern union {...@@ -822,6 +838,7 @@ pub const Type = extern union {
822 .return_type = try payload.return_type.copy(allocator),838 .return_type = try payload.return_type.copy(allocator),
823 .param_types = param_types,839 .param_types = param_types,
824 .cc = payload.cc,840 .cc = payload.cc,
841 .@"addrspace" = payload.@"addrspace",
825 .is_var_args = payload.is_var_args,842 .is_var_args = payload.is_var_args,
826 .is_generic = payload.is_generic,843 .is_generic = payload.is_generic,
827 .comptime_params = comptime_params.ptr,844 .comptime_params = comptime_params.ptr,
...@@ -837,6 +854,7 @@ pub const Type = extern union {...@@ -837,6 +854,7 @@ pub const Type = extern union {
837 .pointee_type = try payload.pointee_type.copy(allocator),854 .pointee_type = try payload.pointee_type.copy(allocator),
838 .sentinel = sent,855 .sentinel = sent,
839 .@"align" = payload.@"align",856 .@"align" = payload.@"align",
857 .@"addrspace" = payload.@"addrspace",
840 .bit_offset = payload.bit_offset,858 .bit_offset = payload.bit_offset,
841 .host_size = payload.host_size,859 .host_size = payload.host_size,
842 .@"allowzero" = payload.@"allowzero",860 .@"allowzero" = payload.@"allowzero",
...@@ -983,6 +1001,9 @@ pub const Type = extern union {...@@ -983,6 +1001,9 @@ pub const Type = extern union {
983 try writer.writeAll(") callconv(.");1001 try writer.writeAll(") callconv(.");
984 try writer.writeAll(@tagName(payload.cc));1002 try writer.writeAll(@tagName(payload.cc));
985 try writer.writeAll(") ");1003 try writer.writeAll(") ");
1004 if (payload.@"addrspace" != .generic) {
1005 try writer.print("addrspace(.{s}) ", .{ @tagName(payload.@"addrspace") });
1006 }
986 ty = payload.return_type;1007 ty = payload.return_type;
987 continue;1008 continue;
988 },1009 },
...@@ -1114,6 +1135,9 @@ pub const Type = extern union {...@@ -1114,6 +1135,9 @@ pub const Type = extern union {
1114 }1135 }
1115 try writer.writeAll(") ");1136 try writer.writeAll(") ");
1116 }1137 }
1138 if (payload.@"addrspace" != .generic) {
1139 try writer.print("addrspace(.{s}) ", .{ @tagName(payload.@"addrspace") });
1140 }
1117 if (!payload.mutable) try writer.writeAll("const ");1141 if (!payload.mutable) try writer.writeAll("const ");
1118 if (payload.@"volatile") try writer.writeAll("volatile ");1142 if (payload.@"volatile") try writer.writeAll("volatile ");
1119 if (payload.@"allowzero") try writer.writeAll("allowzero ");1143 if (payload.@"allowzero") try writer.writeAll("allowzero ");
...@@ -2642,6 +2666,18 @@ pub const Type = extern union {...@@ -2642,6 +2666,18 @@ pub const Type = extern union {
2642 };2666 };
2643 }2667 }
26442668
2669 pub fn fnAddressSpace(self: Type) std.builtin.AddressSpace {
2670 return switch (self.tag()) {
2671 .fn_noreturn_no_args => .generic,
2672 .fn_void_no_args => .generic,
2673 .fn_naked_noreturn_no_args => .generic,
2674 .fn_ccc_void_no_args => .generic,
2675 .function => self.castTag(.function).?.data.@"addrspace",
2676
2677 else => unreachable,
2678 };
2679 }
2680
2645 pub fn fnInfo(ty: Type) Payload.Function.Data {2681 pub fn fnInfo(ty: Type) Payload.Function.Data {
2646 return switch (ty.tag()) {2682 return switch (ty.tag()) {
2647 .fn_noreturn_no_args => .{2683 .fn_noreturn_no_args => .{
...@@ -2649,6 +2685,7 @@ pub const Type = extern union {...@@ -2649,6 +2685,7 @@ pub const Type = extern union {
2649 .comptime_params = undefined,2685 .comptime_params = undefined,
2650 .return_type = initTag(.noreturn),2686 .return_type = initTag(.noreturn),
2651 .cc = .Unspecified,2687 .cc = .Unspecified,
2688 .@"addrspace" = .generic,
2652 .is_var_args = false,2689 .is_var_args = false,
2653 .is_generic = false,2690 .is_generic = false,
2654 },2691 },
...@@ -2657,6 +2694,7 @@ pub const Type = extern union {...@@ -2657,6 +2694,7 @@ pub const Type = extern union {
2657 .comptime_params = undefined,2694 .comptime_params = undefined,
2658 .return_type = initTag(.void),2695 .return_type = initTag(.void),
2659 .cc = .Unspecified,2696 .cc = .Unspecified,
2697 .@"addrspace" = .generic,
2660 .is_var_args = false,2698 .is_var_args = false,
2661 .is_generic = false,2699 .is_generic = false,
2662 },2700 },
...@@ -2665,6 +2703,7 @@ pub const Type = extern union {...@@ -2665,6 +2703,7 @@ pub const Type = extern union {
2665 .comptime_params = undefined,2703 .comptime_params = undefined,
2666 .return_type = initTag(.noreturn),2704 .return_type = initTag(.noreturn),
2667 .cc = .Naked,2705 .cc = .Naked,
2706 .@"addrspace" = .generic,
2668 .is_var_args = false,2707 .is_var_args = false,
2669 .is_generic = false,2708 .is_generic = false,
2670 },2709 },
...@@ -2673,6 +2712,7 @@ pub const Type = extern union {...@@ -2673,6 +2712,7 @@ pub const Type = extern union {
2673 .comptime_params = undefined,2712 .comptime_params = undefined,
2674 .return_type = initTag(.void),2713 .return_type = initTag(.void),
2675 .cc = .C,2714 .cc = .C,
2715 .@"addrspace" = .generic,
2676 .is_var_args = false,2716 .is_var_args = false,
2677 .is_generic = false,2717 .is_generic = false,
2678 },2718 },
...@@ -3544,6 +3584,7 @@ pub const Type = extern union {...@@ -3544,6 +3584,7 @@ pub const Type = extern union {
3544 comptime_params: [*]bool,3584 comptime_params: [*]bool,
3545 return_type: Type,3585 return_type: Type,
3546 cc: std.builtin.CallingConvention,3586 cc: std.builtin.CallingConvention,
3587 @"addrspace": std.builtin.AddressSpace,
3547 is_var_args: bool,3588 is_var_args: bool,
3548 is_generic: bool,3589 is_generic: bool,
35493590
...@@ -3581,6 +3622,7 @@ pub const Type = extern union {...@@ -3581,6 +3622,7 @@ pub const Type = extern union {
3581 sentinel: ?Value,3622 sentinel: ?Value,
3582 /// If zero use pointee_type.AbiAlign()3623 /// If zero use pointee_type.AbiAlign()
3583 @"align": u32,3624 @"align": u32,
3625 @"addrspace": std.builtin.AddressSpace,
3584 bit_offset: u16,3626 bit_offset: u16,
3585 host_size: u16,3627 host_size: u16,
3586 @"allowzero": bool,3628 @"allowzero": bool,