| ... | ... | @@ -248,6 +248,9 @@ pub const Export = struct { |
| 248 | 248 | link: link.File.Export, |
| 249 | 249 | /// The Decl that performs the export. Note that this is *not* the Decl being exported. |
| 250 | 250 | owner_decl: *Decl, |
| 251 | /// The Decl containing the export statement. Inline function calls |
| 252 | /// may cause this to be different from the owner_decl. |
| 253 | src_decl: *Decl, |
| 251 | 254 | /// The Decl being exported. Note this is *not* the Decl performing the export. |
| 252 | 255 | exported_decl: *Decl, |
| 253 | 256 | status: enum { |
| ... | ... | @@ -261,8 +264,8 @@ pub const Export = struct { |
| 261 | 264 | |
| 262 | 265 | pub fn getSrcLoc(exp: Export) SrcLoc { |
| 263 | 266 | return .{ |
| 264 | | .file_scope = exp.owner_decl.namespace.file_scope, |
| 265 | | .parent_decl_node = exp.owner_decl.src_node, |
| 267 | .file_scope = exp.src_decl.namespace.file_scope, |
| 268 | .parent_decl_node = exp.src_decl.src_node, |
| 266 | 269 | .lazy = exp.src, |
| 267 | 270 | }; |
| 268 | 271 | } |
| ... | ... | @@ -1014,15 +1017,6 @@ pub const Scope = struct { |
| 1014 | 1017 | return @fieldParentPtr(T, "base", base); |
| 1015 | 1018 | } |
| 1016 | 1019 | |
| 1017 | | /// Get the decl that is currently being analyzed |
| 1018 | | pub fn ownerDecl(scope: *Scope) ?*Decl { |
| 1019 | | return switch (scope.tag) { |
| 1020 | | .block => scope.cast(Block).?.sema.owner_decl, |
| 1021 | | .file => null, |
| 1022 | | .namespace => null, |
| 1023 | | }; |
| 1024 | | } |
| 1025 | | |
| 1026 | 1020 | /// Get the decl which contains this decl, for the purposes of source reporting |
| 1027 | 1021 | pub fn srcDecl(scope: *Scope) ?*Decl { |
| 1028 | 1022 | return switch (scope.tag) { |
| ... | ... | @@ -3402,7 +3396,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { |
| 3402 | 3396 | } |
| 3403 | 3397 | // The scope needs to have the decl in it. |
| 3404 | 3398 | const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) }; |
| 3405 | | try mod.analyzeExport(&block_scope.base, export_src, options, decl); |
| 3399 | try mod.analyzeExport(&block_scope, export_src, options, decl); |
| 3406 | 3400 | } |
| 3407 | 3401 | return type_changed or is_inline != prev_is_inline; |
| 3408 | 3402 | } |
| ... | ... | @@ -3462,7 +3456,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { |
| 3462 | 3456 | const export_src = src; // TODO point to the export token |
| 3463 | 3457 | // The scope needs to have the decl in it. |
| 3464 | 3458 | const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) }; |
| 3465 | | try mod.analyzeExport(&block_scope.base, export_src, options, decl); |
| 3459 | try mod.analyzeExport(&block_scope, export_src, options, decl); |
| 3466 | 3460 | } |
| 3467 | 3461 | |
| 3468 | 3462 | return type_changed; |
| ... | ... | @@ -3931,7 +3925,7 @@ pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void { |
| 3931 | 3925 | |
| 3932 | 3926 | pub fn deleteAnonDecl(mod: *Module, scope: *Scope, decl: *Decl) void { |
| 3933 | 3927 | log.debug("deleteAnonDecl {*} ({s})", .{ decl, decl.name }); |
| 3934 | | const scope_decl = scope.ownerDecl().?; |
| 3928 | const scope_decl = scope.srcDecl().?; |
| 3935 | 3929 | assert(scope_decl.namespace.anon_decls.swapRemove(decl)); |
| 3936 | 3930 | decl.destroy(mod); |
| 3937 | 3931 | } |
| ... | ... | @@ -4209,7 +4203,7 @@ pub fn getErrorValue(mod: *Module, name: []const u8) !std.StringHashMapUnmanaged |
| 4209 | 4203 | |
| 4210 | 4204 | pub fn analyzeExport( |
| 4211 | 4205 | mod: *Module, |
| 4212 | | scope: *Scope, |
| 4206 | block: *Scope.Block, |
| 4213 | 4207 | src: LazySrcLoc, |
| 4214 | 4208 | borrowed_options: std.builtin.ExportOptions, |
| 4215 | 4209 | exported_decl: *Decl, |
| ... | ... | @@ -4217,7 +4211,7 @@ pub fn analyzeExport( |
| 4217 | 4211 | try mod.ensureDeclAnalyzed(exported_decl); |
| 4218 | 4212 | switch (exported_decl.ty.zigTypeTag()) { |
| 4219 | 4213 | .Fn => {}, |
| 4220 | | else => return mod.fail(scope, src, "unable to export type '{}'", .{exported_decl.ty}), |
| 4214 | else => return mod.fail(&block.base, src, "unable to export type '{}'", .{exported_decl.ty}), |
| 4221 | 4215 | } |
| 4222 | 4216 | |
| 4223 | 4217 | const gpa = mod.gpa; |
| ... | ... | @@ -4234,7 +4228,8 @@ pub fn analyzeExport( |
| 4234 | 4228 | const section: ?[]const u8 = if (borrowed_options.section) |s| try gpa.dupe(u8, s) else null; |
| 4235 | 4229 | errdefer if (section) |s| gpa.free(s); |
| 4236 | 4230 | |
| 4237 | | const owner_decl = scope.ownerDecl().?; |
| 4231 | const src_decl = block.src_decl; |
| 4232 | const owner_decl = block.sema.owner_decl; |
| 4238 | 4233 | |
| 4239 | 4234 | log.debug("exporting Decl '{s}' as symbol '{s}' from Decl '{s}'", .{ |
| 4240 | 4235 | exported_decl.name, symbol_name, owner_decl.name, |
| ... | ... | @@ -4257,6 +4252,7 @@ pub fn analyzeExport( |
| 4257 | 4252 | .spirv => .{ .spirv = {} }, |
| 4258 | 4253 | }, |
| 4259 | 4254 | .owner_decl = owner_decl, |
| 4255 | .src_decl = src_decl, |
| 4260 | 4256 | .exported_decl = exported_decl, |
| 4261 | 4257 | .status = .in_progress, |
| 4262 | 4258 | }; |
| ... | ... | @@ -4287,38 +4283,38 @@ pub fn createAnonymousDeclNamed( |
| 4287 | 4283 | typed_value: TypedValue, |
| 4288 | 4284 | name: [:0]u8, |
| 4289 | 4285 | ) !*Decl { |
| 4290 | | return mod.createAnonymousDeclFromDeclNamed(scope.ownerDecl().?, scope.srcScope(), typed_value, name); |
| 4286 | return mod.createAnonymousDeclFromDeclNamed(scope.srcDecl().?, scope.srcScope(), typed_value, name); |
| 4291 | 4287 | } |
| 4292 | 4288 | |
| 4293 | 4289 | pub fn createAnonymousDecl(mod: *Module, scope: *Scope, typed_value: TypedValue) !*Decl { |
| 4294 | | return mod.createAnonymousDeclFromDecl(scope.ownerDecl().?, scope.srcScope(), typed_value); |
| 4290 | return mod.createAnonymousDeclFromDecl(scope.srcDecl().?, scope.srcScope(), typed_value); |
| 4295 | 4291 | } |
| 4296 | 4292 | |
| 4297 | | pub fn createAnonymousDeclFromDecl(mod: *Module, owner_decl: *Decl, src_scope: ?*CaptureScope, tv: TypedValue) !*Decl { |
| 4293 | pub fn createAnonymousDeclFromDecl(mod: *Module, src_decl: *Decl, src_scope: ?*CaptureScope, tv: TypedValue) !*Decl { |
| 4298 | 4294 | const name_index = mod.getNextAnonNameIndex(); |
| 4299 | 4295 | const name = try std.fmt.allocPrintZ(mod.gpa, "{s}__anon_{d}", .{ |
| 4300 | | owner_decl.name, name_index, |
| 4296 | src_decl.name, name_index, |
| 4301 | 4297 | }); |
| 4302 | | return mod.createAnonymousDeclFromDeclNamed(owner_decl, src_scope, tv, name); |
| 4298 | return mod.createAnonymousDeclFromDeclNamed(src_decl, src_scope, tv, name); |
| 4303 | 4299 | } |
| 4304 | 4300 | |
| 4305 | 4301 | /// Takes ownership of `name` even if it returns an error. |
| 4306 | 4302 | pub fn createAnonymousDeclFromDeclNamed( |
| 4307 | 4303 | mod: *Module, |
| 4308 | | owner_decl: *Decl, |
| 4304 | src_decl: *Decl, |
| 4309 | 4305 | src_scope: ?*CaptureScope, |
| 4310 | 4306 | typed_value: TypedValue, |
| 4311 | 4307 | name: [:0]u8, |
| 4312 | 4308 | ) !*Decl { |
| 4313 | 4309 | errdefer mod.gpa.free(name); |
| 4314 | 4310 | |
| 4315 | | const namespace = owner_decl.namespace; |
| 4311 | const namespace = src_decl.namespace; |
| 4316 | 4312 | try namespace.anon_decls.ensureUnusedCapacity(mod.gpa, 1); |
| 4317 | 4313 | |
| 4318 | | const new_decl = try mod.allocateNewDecl(namespace, owner_decl.src_node, src_scope); |
| 4314 | const new_decl = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope); |
| 4319 | 4315 | |
| 4320 | 4316 | new_decl.name = name; |
| 4321 | | new_decl.src_line = owner_decl.src_line; |
| 4317 | new_decl.src_line = src_decl.src_line; |
| 4322 | 4318 | new_decl.ty = typed_value.ty; |
| 4323 | 4319 | new_decl.val = typed_value.val; |
| 4324 | 4320 | new_decl.align_val = Value.initTag(.null_value); |