| ... | @@ -2161,6 +2161,10 @@ pub const SrcLoc = struct { | ... | @@ -2161,6 +2161,10 @@ pub const SrcLoc = struct { |
| 2161 | .local_var_decl => tree.localVarDecl(node), | 2161 | .local_var_decl => tree.localVarDecl(node), |
| 2162 | .simple_var_decl => tree.simpleVarDecl(node), | 2162 | .simple_var_decl => tree.simpleVarDecl(node), |
| 2163 | .aligned_var_decl => tree.alignedVarDecl(node), | 2163 | .aligned_var_decl => tree.alignedVarDecl(node), |
| | 2164 | .@"usingnamespace" => { |
| | 2165 | const node_data = tree.nodes.items(.data); |
| | 2166 | return nodeToSpan(tree, node_data[node].lhs); |
| | 2167 | }, |
| 2164 | else => unreachable, | 2168 | else => unreachable, |
| 2165 | }; | 2169 | }; |
| 2166 | if (full.ast.type_node != 0) { | 2170 | if (full.ast.type_node != 0) { |
| ... | @@ -2171,6 +2175,58 @@ pub const SrcLoc = struct { | ... | @@ -2171,6 +2175,58 @@ pub const SrcLoc = struct { |
| 2171 | const end = start + @intCast(u32, tree.tokenSlice(tok_index).len); | 2175 | const end = start + @intCast(u32, tree.tokenSlice(tok_index).len); |
| 2172 | return Span{ .start = start, .end = end, .main = start }; | 2176 | return Span{ .start = start, .end = end, .main = start }; |
| 2173 | }, | 2177 | }, |
| | 2178 | .node_offset_var_decl_align => |node_off| { |
| | 2179 | const tree = try src_loc.file_scope.getTree(gpa); |
| | 2180 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| | 2181 | const node_tags = tree.nodes.items(.tag); |
| | 2182 | const full: Ast.full.VarDecl = switch (node_tags[node]) { |
| | 2183 | .global_var_decl => tree.globalVarDecl(node), |
| | 2184 | .local_var_decl => tree.localVarDecl(node), |
| | 2185 | .simple_var_decl => tree.simpleVarDecl(node), |
| | 2186 | .aligned_var_decl => tree.alignedVarDecl(node), |
| | 2187 | else => unreachable, |
| | 2188 | }; |
| | 2189 | return nodeToSpan(tree, full.ast.align_node); |
| | 2190 | }, |
| | 2191 | .node_offset_var_decl_section => |node_off| { |
| | 2192 | const tree = try src_loc.file_scope.getTree(gpa); |
| | 2193 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| | 2194 | const node_tags = tree.nodes.items(.tag); |
| | 2195 | const full: Ast.full.VarDecl = switch (node_tags[node]) { |
| | 2196 | .global_var_decl => tree.globalVarDecl(node), |
| | 2197 | .local_var_decl => tree.localVarDecl(node), |
| | 2198 | .simple_var_decl => tree.simpleVarDecl(node), |
| | 2199 | .aligned_var_decl => tree.alignedVarDecl(node), |
| | 2200 | else => unreachable, |
| | 2201 | }; |
| | 2202 | return nodeToSpan(tree, full.ast.section_node); |
| | 2203 | }, |
| | 2204 | .node_offset_var_decl_addrspace => |node_off| { |
| | 2205 | const tree = try src_loc.file_scope.getTree(gpa); |
| | 2206 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| | 2207 | const node_tags = tree.nodes.items(.tag); |
| | 2208 | const full: Ast.full.VarDecl = switch (node_tags[node]) { |
| | 2209 | .global_var_decl => tree.globalVarDecl(node), |
| | 2210 | .local_var_decl => tree.localVarDecl(node), |
| | 2211 | .simple_var_decl => tree.simpleVarDecl(node), |
| | 2212 | .aligned_var_decl => tree.alignedVarDecl(node), |
| | 2213 | else => unreachable, |
| | 2214 | }; |
| | 2215 | return nodeToSpan(tree, full.ast.addrspace_node); |
| | 2216 | }, |
| | 2217 | .node_offset_var_decl_init => |node_off| { |
| | 2218 | const tree = try src_loc.file_scope.getTree(gpa); |
| | 2219 | const node = src_loc.declRelativeToNodeIndex(node_off); |
| | 2220 | const node_tags = tree.nodes.items(.tag); |
| | 2221 | const full: Ast.full.VarDecl = switch (node_tags[node]) { |
| | 2222 | .global_var_decl => tree.globalVarDecl(node), |
| | 2223 | .local_var_decl => tree.localVarDecl(node), |
| | 2224 | .simple_var_decl => tree.simpleVarDecl(node), |
| | 2225 | .aligned_var_decl => tree.alignedVarDecl(node), |
| | 2226 | else => unreachable, |
| | 2227 | }; |
| | 2228 | return nodeToSpan(tree, full.ast.init_node); |
| | 2229 | }, |
| 2174 | .node_offset_builtin_call_arg0 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 0), | 2230 | .node_offset_builtin_call_arg0 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 0), |
| 2175 | .node_offset_builtin_call_arg1 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 1), | 2231 | .node_offset_builtin_call_arg1 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 1), |
| 2176 | .node_offset_builtin_call_arg2 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 2), | 2232 | .node_offset_builtin_call_arg2 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 2), |
| ... | @@ -2857,6 +2913,18 @@ pub const LazySrcLoc = union(enum) { | ... | @@ -2857,6 +2913,18 @@ pub const LazySrcLoc = union(enum) { |
| 2857 | /// to the type expression. | 2913 | /// to the type expression. |
| 2858 | /// The Decl is determined contextually. | 2914 | /// The Decl is determined contextually. |
| 2859 | node_offset_var_decl_ty: i32, | 2915 | node_offset_var_decl_ty: i32, |
| | 2916 | /// The source location points to the alignment expression of a var decl. |
| | 2917 | /// The Decl is determined contextually. |
| | 2918 | node_offset_var_decl_align: i32, |
| | 2919 | /// The source location points to the linksection expression of a var decl. |
| | 2920 | /// The Decl is determined contextually. |
| | 2921 | node_offset_var_decl_section: i32, |
| | 2922 | /// The source location points to the addrspace expression of a var decl. |
| | 2923 | /// The Decl is determined contextually. |
| | 2924 | node_offset_var_decl_addrspace: i32, |
| | 2925 | /// The source location points to the initializer of a var decl. |
| | 2926 | /// The Decl is determined contextually. |
| | 2927 | node_offset_var_decl_init: i32, |
| 2860 | /// The source location points to a for loop condition expression, | 2928 | /// The source location points to a for loop condition expression, |
| 2861 | /// found by taking this AST node index offset from the containing | 2929 | /// found by taking this AST node index offset from the containing |
| 2862 | /// Decl AST node, which points to a for loop AST node. Next, navigate | 2930 | /// Decl AST node, which points to a for loop AST node. Next, navigate |
| ... | @@ -3098,6 +3166,10 @@ pub const LazySrcLoc = union(enum) { | ... | @@ -3098,6 +3166,10 @@ pub const LazySrcLoc = union(enum) { |
| 3098 | .node_offset, | 3166 | .node_offset, |
| 3099 | .node_offset_initializer, | 3167 | .node_offset_initializer, |
| 3100 | .node_offset_var_decl_ty, | 3168 | .node_offset_var_decl_ty, |
| | 3169 | .node_offset_var_decl_align, |
| | 3170 | .node_offset_var_decl_section, |
| | 3171 | .node_offset_var_decl_addrspace, |
| | 3172 | .node_offset_var_decl_init, |
| 3101 | .node_offset_for_cond, | 3173 | .node_offset_for_cond, |
| 3102 | .node_offset_builtin_call_arg0, | 3174 | .node_offset_builtin_call_arg0, |
| 3103 | .node_offset_builtin_call_arg1, | 3175 | .node_offset_builtin_call_arg1, |
| ... | @@ -4414,17 +4486,26 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { | ... | @@ -4414,17 +4486,26 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 4414 | const body = zir.extra[extra.end..][0..extra.data.body_len]; | 4486 | const body = zir.extra[extra.end..][0..extra.data.body_len]; |
| 4415 | const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand; | 4487 | const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand; |
| 4416 | try wip_captures.finalize(); | 4488 | try wip_captures.finalize(); |
| 4417 | const src = LazySrcLoc.nodeOffset(0); | 4489 | const align_src: LazySrcLoc = .{ .node_offset_var_decl_align = 0 }; |
| 4418 | const decl_tv = try sema.resolveInstValue(&block_scope, .unneeded, result_ref, undefined); | 4490 | const section_src: LazySrcLoc = .{ .node_offset_var_decl_section = 0 }; |
| | 4491 | const address_space_src: LazySrcLoc = .{ .node_offset_var_decl_addrspace = 0 }; |
| | 4492 | const ty_src: LazySrcLoc = .{ .node_offset_var_decl_ty = 0 }; |
| | 4493 | const init_src: LazySrcLoc = .{ .node_offset_var_decl_init = 0 }; |
| | 4494 | const decl_tv = try sema.resolveInstValue(&block_scope, init_src, result_ref, undefined); |
| 4419 | const decl_align: u32 = blk: { | 4495 | const decl_align: u32 = blk: { |
| 4420 | const align_ref = decl.zirAlignRef(); | 4496 | const align_ref = decl.zirAlignRef(); |
| 4421 | if (align_ref == .none) break :blk 0; | 4497 | if (align_ref == .none) break :blk 0; |
| 4422 | break :blk try sema.resolveAlign(&block_scope, src, align_ref); | 4498 | break :blk try sema.resolveAlign(&block_scope, align_src, align_ref); |
| 4423 | }; | 4499 | }; |
| 4424 | const decl_linksection: ?[*:0]const u8 = blk: { | 4500 | const decl_linksection: ?[*:0]const u8 = blk: { |
| 4425 | const linksection_ref = decl.zirLinksectionRef(); | 4501 | const linksection_ref = decl.zirLinksectionRef(); |
| 4426 | if (linksection_ref == .none) break :blk null; | 4502 | if (linksection_ref == .none) break :blk null; |
| 4427 | const bytes = try sema.resolveConstString(&block_scope, src, linksection_ref, "linksection must be comptime known"); | 4503 | const bytes = try sema.resolveConstString(&block_scope, section_src, linksection_ref, "linksection must be comptime known"); |
| | 4504 | if (mem.indexOfScalar(u8, bytes, 0) != null) { |
| | 4505 | return sema.fail(&block_scope, section_src, "linksection cannot contain null bytes", .{}); |
| | 4506 | } else if (bytes.len == 0) { |
| | 4507 | return sema.fail(&block_scope, section_src, "linksection cannot be empty", .{}); |
| | 4508 | } |
| 4428 | break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr; | 4509 | break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr; |
| 4429 | }; | 4510 | }; |
| 4430 | const target = sema.mod.getTarget(); | 4511 | const target = sema.mod.getTarget(); |
| ... | @@ -4442,27 +4523,27 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { | ... | @@ -4442,27 +4523,27 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 4442 | .constant => target_util.defaultAddressSpace(target, .global_constant), | 4523 | .constant => target_util.defaultAddressSpace(target, .global_constant), |
| 4443 | else => unreachable, | 4524 | else => unreachable, |
| 4444 | }, | 4525 | }, |
| 4445 | else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, src, addrspace_ref, addrspace_ctx), | 4526 | else => |addrspace_ref| try sema.analyzeAddrspace(&block_scope, address_space_src, addrspace_ref, addrspace_ctx), |
| 4446 | }; | 4527 | }; |
| 4447 | }; | 4528 | }; |
| 4448 | | 4529 | |
| 4449 | // Note this resolves the type of the Decl, not the value; if this Decl | 4530 | // Note this resolves the type of the Decl, not the value; if this Decl |
| 4450 | // is a struct, for example, this resolves `type` (which needs no resolution), | 4531 | // is a struct, for example, this resolves `type` (which needs no resolution), |
| 4451 | // not the struct itself. | 4532 | // not the struct itself. |
| 4452 | try sema.resolveTypeLayout(&block_scope, src, decl_tv.ty); | 4533 | try sema.resolveTypeLayout(&block_scope, ty_src, decl_tv.ty); |
| 4453 | | 4534 | |
| 4454 | const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State); | 4535 | const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State); |
| 4455 | | 4536 | |
| 4456 | if (decl.is_usingnamespace) { | 4537 | if (decl.is_usingnamespace) { |
| 4457 | if (!decl_tv.ty.eql(Type.type, mod)) { | 4538 | if (!decl_tv.ty.eql(Type.type, mod)) { |
| 4458 | return sema.fail(&block_scope, src, "expected type, found {}", .{ | 4539 | return sema.fail(&block_scope, ty_src, "expected type, found {}", .{ |
| 4459 | decl_tv.ty.fmt(mod), | 4540 | decl_tv.ty.fmt(mod), |
| 4460 | }); | 4541 | }); |
| 4461 | } | 4542 | } |
| 4462 | var buffer: Value.ToTypeBuffer = undefined; | 4543 | var buffer: Value.ToTypeBuffer = undefined; |
| 4463 | const ty = try decl_tv.val.toType(&buffer).copy(decl_arena_allocator); | 4544 | const ty = try decl_tv.val.toType(&buffer).copy(decl_arena_allocator); |
| 4464 | if (ty.getNamespace() == null) { | 4545 | if (ty.getNamespace() == null) { |
| 4465 | return sema.fail(&block_scope, src, "type {} has no namespace", .{ty.fmt(mod)}); | 4546 | return sema.fail(&block_scope, ty_src, "type {} has no namespace", .{ty.fmt(mod)}); |
| 4466 | } | 4547 | } |
| 4467 | | 4548 | |
| 4468 | decl.ty = Type.type; | 4549 | decl.ty = Type.type; |
| ... | @@ -4508,7 +4589,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { | ... | @@ -4508,7 +4589,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 4508 | decl.analysis = .complete; | 4589 | decl.analysis = .complete; |
| 4509 | decl.generation = mod.generation; | 4590 | decl.generation = mod.generation; |
| 4510 | | 4591 | |
| 4511 | const has_runtime_bits = try sema.fnHasRuntimeBits(&block_scope, src, decl.ty); | 4592 | const has_runtime_bits = try sema.fnHasRuntimeBits(&block_scope, ty_src, decl.ty); |
| 4512 | | 4593 | |
| 4513 | if (has_runtime_bits) { | 4594 | if (has_runtime_bits) { |
| 4514 | // We don't fully codegen the decl until later, but we do need to reserve a global | 4595 | // We don't fully codegen the decl until later, but we do need to reserve a global |
| ... | @@ -4525,7 +4606,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { | ... | @@ -4525,7 +4606,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 4525 | | 4606 | |
| 4526 | const is_inline = decl.ty.fnCallingConvention() == .Inline; | 4607 | const is_inline = decl.ty.fnCallingConvention() == .Inline; |
| 4527 | if (decl.is_exported) { | 4608 | if (decl.is_exported) { |
| 4528 | const export_src = src; // TODO make this point at `export` token | 4609 | const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) }; |
| 4529 | if (is_inline) { | 4610 | if (is_inline) { |
| 4530 | return sema.fail(&block_scope, export_src, "export of inline function", .{}); | 4611 | return sema.fail(&block_scope, export_src, "export of inline function", .{}); |
| 4531 | } | 4612 | } |
| ... | @@ -4588,14 +4669,14 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { | ... | @@ -4588,14 +4669,14 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 4588 | decl.generation = mod.generation; | 4669 | decl.generation = mod.generation; |
| 4589 | | 4670 | |
| 4590 | const has_runtime_bits = is_extern or | 4671 | const has_runtime_bits = is_extern or |
| 4591 | (queue_linker_work and try sema.typeHasRuntimeBits(&block_scope, src, decl.ty)); | 4672 | (queue_linker_work and try sema.typeHasRuntimeBits(&block_scope, ty_src, decl.ty)); |
| 4592 | | 4673 | |
| 4593 | if (has_runtime_bits) { | 4674 | if (has_runtime_bits) { |
| 4594 | log.debug("queue linker work for {*} ({s})", .{ decl, decl.name }); | 4675 | log.debug("queue linker work for {*} ({s})", .{ decl, decl.name }); |
| 4595 | | 4676 | |
| 4596 | // Needed for codegen_decl which will call updateDecl and then the | 4677 | // Needed for codegen_decl which will call updateDecl and then the |
| 4597 | // codegen backend wants full access to the Decl Type. | 4678 | // codegen backend wants full access to the Decl Type. |
| 4598 | try sema.resolveTypeFully(&block_scope, src, decl.ty); | 4679 | try sema.resolveTypeFully(&block_scope, ty_src, decl.ty); |
| 4599 | | 4680 | |
| 4600 | try mod.comp.bin_file.allocateDeclIndexes(decl_index); | 4681 | try mod.comp.bin_file.allocateDeclIndexes(decl_index); |
| 4601 | try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index }); | 4682 | try mod.comp.work_queue.writeItem(.{ .codegen_decl = decl_index }); |
| ... | @@ -4606,7 +4687,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { | ... | @@ -4606,7 +4687,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 4606 | } | 4687 | } |
| 4607 | | 4688 | |
| 4608 | if (decl.is_exported) { | 4689 | if (decl.is_exported) { |
| 4609 | const export_src = src; // TODO point to the export token | 4690 | const export_src: LazySrcLoc = .{ .token_offset = @boolToInt(decl.is_pub) }; |
| 4610 | // The scope needs to have the decl in it. | 4691 | // The scope needs to have the decl in it. |
| 4611 | const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) }; | 4692 | const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) }; |
| 4612 | try sema.analyzeExport(&block_scope, export_src, options, decl_index); | 4693 | try sema.analyzeExport(&block_scope, export_src, options, decl_index); |