| ... | ... | @@ -2161,6 +2161,10 @@ pub const SrcLoc = struct { |
| 2161 | 2161 | .local_var_decl => tree.localVarDecl(node), |
| 2162 | 2162 | .simple_var_decl => tree.simpleVarDecl(node), |
| 2163 | 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 | 2168 | else => unreachable, |
| 2165 | 2169 | }; |
| 2166 | 2170 | if (full.ast.type_node != 0) { |
| ... | ... | @@ -2171,6 +2175,58 @@ pub const SrcLoc = struct { |
| 2171 | 2175 | const end = start + @intCast(u32, tree.tokenSlice(tok_index).len); |
| 2172 | 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 | 2230 | .node_offset_builtin_call_arg0 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 0), |
| 2175 | 2231 | .node_offset_builtin_call_arg1 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 1), |
| 2176 | 2232 | .node_offset_builtin_call_arg2 => |n| return src_loc.byteOffsetBuiltinCallArg(gpa, n, 2), |
| ... | ... | @@ -2857,6 +2913,18 @@ pub const LazySrcLoc = union(enum) { |
| 2857 | 2913 | /// to the type expression. |
| 2858 | 2914 | /// The Decl is determined contextually. |
| 2859 | 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 | 2928 | /// The source location points to a for loop condition expression, |
| 2861 | 2929 | /// found by taking this AST node index offset from the containing |
| 2862 | 2930 | /// Decl AST node, which points to a for loop AST node. Next, navigate |
| ... | ... | @@ -3098,6 +3166,10 @@ pub const LazySrcLoc = union(enum) { |
| 3098 | 3166 | .node_offset, |
| 3099 | 3167 | .node_offset_initializer, |
| 3100 | 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 | 3173 | .node_offset_for_cond, |
| 3102 | 3174 | .node_offset_builtin_call_arg0, |
| 3103 | 3175 | .node_offset_builtin_call_arg1, |
| ... | ... | @@ -4414,17 +4486,26 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 4414 | 4486 | const body = zir.extra[extra.end..][0..extra.data.body_len]; |
| 4415 | 4487 | const result_ref = (try sema.analyzeBodyBreak(&block_scope, body)).?.operand; |
| 4416 | 4488 | try wip_captures.finalize(); |
| 4417 | | const src = LazySrcLoc.nodeOffset(0); |
| 4418 | | const decl_tv = try sema.resolveInstValue(&block_scope, .unneeded, result_ref, undefined); |
| 4489 | const align_src: LazySrcLoc = .{ .node_offset_var_decl_align = 0 }; |
| 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 | 4495 | const decl_align: u32 = blk: { |
| 4420 | 4496 | const align_ref = decl.zirAlignRef(); |
| 4421 | 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 | 4500 | const decl_linksection: ?[*:0]const u8 = blk: { |
| 4425 | 4501 | const linksection_ref = decl.zirLinksectionRef(); |
| 4426 | 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 | 4509 | break :blk (try decl_arena_allocator.dupeZ(u8, bytes)).ptr; |
| 4429 | 4510 | }; |
| 4430 | 4511 | const target = sema.mod.getTarget(); |
| ... | ... | @@ -4442,27 +4523,27 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 4442 | 4523 | .constant => target_util.defaultAddressSpace(target, .global_constant), |
| 4443 | 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 | 4530 | // Note this resolves the type of the Decl, not the value; if this Decl |
| 4450 | 4531 | // is a struct, for example, this resolves `type` (which needs no resolution), |
| 4451 | 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 | 4535 | const decl_arena_state = try decl_arena_allocator.create(std.heap.ArenaAllocator.State); |
| 4455 | 4536 | |
| 4456 | 4537 | if (decl.is_usingnamespace) { |
| 4457 | 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 | 4540 | decl_tv.ty.fmt(mod), |
| 4460 | 4541 | }); |
| 4461 | 4542 | } |
| 4462 | 4543 | var buffer: Value.ToTypeBuffer = undefined; |
| 4463 | 4544 | const ty = try decl_tv.val.toType(&buffer).copy(decl_arena_allocator); |
| 4464 | 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 | 4549 | decl.ty = Type.type; |
| ... | ... | @@ -4508,7 +4589,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool { |
| 4508 | 4589 | decl.analysis = .complete; |
| 4509 | 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 | 4594 | if (has_runtime_bits) { |
| 4514 | 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 | 4606 | |
| 4526 | 4607 | const is_inline = decl.ty.fnCallingConvention() == .Inline; |
| 4527 | 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 | 4610 | if (is_inline) { |
| 4530 | 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 | 4669 | decl.generation = mod.generation; |
| 4589 | 4670 | |
| 4590 | 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 | 4674 | if (has_runtime_bits) { |
| 4594 | 4675 | log.debug("queue linker work for {*} ({s})", .{ decl, decl.name }); |
| 4595 | 4676 | |
| 4596 | 4677 | // Needed for codegen_decl which will call updateDecl and then the |
| 4597 | 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 | 4681 | try mod.comp.bin_file.allocateDeclIndexes(decl_index); |
| 4601 | 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 | 4687 | } |
| 4607 | 4688 | |
| 4608 | 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 | 4691 | // The scope needs to have the decl in it. |
| 4611 | 4692 | const options: std.builtin.ExportOptions = .{ .name = mem.sliceTo(decl.name, 0) }; |
| 4612 | 4693 | try sema.analyzeExport(&block_scope, export_src, options, decl_index); |