| author | |
| committer | |
| log | 332eafeb7f3d866556ab767b960a04661bc43bc7 |
| tree | d299cbc233ca756ca42885e66f54e2b08f2a3d9a |
| parent | c05a20fc8c36742dab8792d15e79716da1a55759 |
Ran into a design flaw here which will need to get solved by having
AstGen annotate ZIR with which instructions are closed over.18 files changed, 385 insertions(+), 243 deletions(-)
src/AstGen.zig+4-1| ... | @@ -6416,6 +6416,9 @@ fn identifier( | ... | @@ -6416,6 +6416,9 @@ fn identifier( |
| 6416 | }, | 6416 | }, |
| 6417 | .top => break, | 6417 | .top => break, |
| 6418 | }; | 6418 | }; |
| 6419 | if (found_already == null) { | ||
| 6420 | return astgen.failNode(ident, "use of undeclared identifier '{s}'", .{ident_name}); | ||
| 6421 | } | ||
| 6419 | 6422 | ||
| 6420 | // Decl references happen by name rather than ZIR index so that when unrelated | 6423 | // Decl references happen by name rather than ZIR index so that when unrelated |
| 6421 | // decls are modified, ZIR code containing references to them can be unmodified. | 6424 | // decls are modified, ZIR code containing references to them can be unmodified. |
| ... | @@ -10052,7 +10055,7 @@ fn isPrimitive(name: []const u8) bool { | ... | @@ -10052,7 +10055,7 @@ fn isPrimitive(name: []const u8) bool { |
| 10052 | } | 10055 | } |
| 10053 | } | 10056 | } |
| 10054 | 10057 | ||
| 10055 | /// Local variables shadowing detection, including function parameters and primitives. | 10058 | /// Local variables shadowing detection, including function parameters. |
| 10056 | fn detectLocalShadowing( | 10059 | fn detectLocalShadowing( |
| 10057 | astgen: *AstGen, | 10060 | astgen: *AstGen, |
| 10058 | scope: *Scope, | 10061 | scope: *Scope, |
src/Module.zig+50-12| ... | @@ -365,6 +365,8 @@ pub const Decl = struct { | ... | @@ -365,6 +365,8 @@ pub const Decl = struct { |
| 365 | /// Decl is marked alive, then it sends the Decl to the linker. Otherwise it | 365 | /// Decl is marked alive, then it sends the Decl to the linker. Otherwise it |
| 366 | /// deletes the Decl on the spot. | 366 | /// deletes the Decl on the spot. |
| 367 | alive: bool, | 367 | alive: bool, |
| 368 | /// Whether the Decl is a `usingnamespace` declaration. | ||
| 369 | is_usingnamespace: bool, | ||
| 368 | 370 | ||
| 369 | /// Represents the position of the code in the output file. | 371 | /// Represents the position of the code in the output file. |
| 370 | /// This is populated regardless of semantic analysis and code generation. | 372 | /// This is populated regardless of semantic analysis and code generation. |
| ... | @@ -1008,6 +1010,11 @@ pub const Scope = struct { | ... | @@ -1008,6 +1010,11 @@ pub const Scope = struct { |
| 1008 | 1010 | ||
| 1009 | anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{}, | 1011 | anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{}, |
| 1010 | 1012 | ||
| 1013 | /// Key is usingnamespace Decl itself. To find the namespace being included, | ||
| 1014 | /// the Decl Value has to be resolved as a Type which has a Namespace. | ||
| 1015 | /// Value is whether the usingnamespace decl is marked `pub`. | ||
| 1016 | usingnamespace_set: std.AutoHashMapUnmanaged(*Decl, bool) = .{}, | ||
| 1017 | |||
| 1011 | pub fn deinit(ns: *Namespace, mod: *Module) void { | 1018 | pub fn deinit(ns: *Namespace, mod: *Module) void { |
| 1012 | ns.destroyDecls(mod); | 1019 | ns.destroyDecls(mod); |
| 1013 | ns.* = undefined; | 1020 | ns.* = undefined; |
| ... | @@ -3174,6 +3181,31 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { | ... | @@ -3174,6 +3181,31 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { |
| 3174 | errdefer decl_arena.deinit(); | 3181 | errdefer decl_arena.deinit(); |
| 3175 | const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State); | 3182 | const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State); |
| 3176 | 3183 | ||
| 3184 | if (decl.is_usingnamespace) { | ||
| 3185 | const ty_ty = Type.initTag(.type); | ||
| 3186 | if (!decl_tv.ty.eql(ty_ty)) { | ||
| 3187 | return mod.fail(&block_scope.base, src, "expected type, found {}", .{decl_tv.ty}); | ||
| 3188 | } | ||
| 3189 | var buffer: Value.ToTypeBuffer = undefined; | ||
| 3190 | const ty = decl_tv.val.toType(&buffer); | ||
| 3191 | if (ty.getNamespace() == null) { | ||
| 3192 | return mod.fail(&block_scope.base, src, "type {} has no namespace", .{ty}); | ||
| 3193 | } | ||
| 3194 | |||
| 3195 | decl.ty = ty_ty; | ||
| 3196 | decl.val = try Value.Tag.ty.create(&decl_arena.allocator, ty); | ||
| 3197 | decl.align_val = Value.initTag(.null_value); | ||
| 3198 | decl.linksection_val = Value.initTag(.null_value); | ||
| 3199 | decl.has_tv = true; | ||
| 3200 | decl.owns_tv = false; | ||
| 3201 | decl_arena_state.* = decl_arena.state; | ||
| 3202 | decl.value_arena = decl_arena_state; | ||
| 3203 | decl.analysis = .complete; | ||
| 3204 | decl.generation = mod.generation; | ||
| 3205 | |||
| 3206 | return true; | ||
| 3207 | } | ||
| 3208 | |||
| 3177 | if (decl_tv.val.castTag(.function)) |fn_payload| { | 3209 | if (decl_tv.val.castTag(.function)) |fn_payload| { |
| 3178 | const func = fn_payload.data; | 3210 | const func = fn_payload.data; |
| 3179 | const owns_tv = func.owner_decl == decl; | 3211 | const owns_tv = func.owner_decl == decl; |
| ... | @@ -3269,16 +3301,13 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { | ... | @@ -3269,16 +3301,13 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool { |
| 3269 | if (type_changed and mod.emit_h != null) { | 3301 | if (type_changed and mod.emit_h != null) { |
| 3270 | try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl }); | 3302 | try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl }); |
| 3271 | } | 3303 | } |
| 3272 | } else if (decl_tv.ty.zigTypeTag() == .Type) { | ||
| 3273 | // In case this Decl is a struct or union, we need to resolve the fields | ||
| 3274 | // while we still have the `Sema` in scope, so that the field type expressions | ||
| 3275 | // can use the resolved AIR instructions that they possibly reference. | ||
| 3276 | // We do this after the decl is populated and set to `complete` so that a `Decl` | ||
| 3277 | // may reference itself. | ||
| 3278 | var buffer: Value.ToTypeBuffer = undefined; | ||
| 3279 | const ty = decl.val.toType(&buffer); | ||
| 3280 | try sema.resolveDeclFields(&block_scope, src, ty); | ||
| 3281 | } | 3304 | } |
| 3305 | // In case this Decl is a struct or union, we need to resolve the fields | ||
| 3306 | // while we still have the `Sema` in scope, so that the field type expressions | ||
| 3307 | // can use the resolved AIR instructions that they possibly reference. | ||
| 3308 | // We do this after the decl is populated and set to `complete` so that a `Decl` | ||
| 3309 | // may reference itself. | ||
| 3310 | try sema.resolvePendingTypes(&block_scope); | ||
| 3282 | 3311 | ||
| 3283 | if (decl.is_exported) { | 3312 | if (decl.is_exported) { |
| 3284 | const export_src = src; // TODO point to the export token | 3313 | const export_src = src; // TODO point to the export token |
| ... | @@ -3494,7 +3523,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi | ... | @@ -3494,7 +3523,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi |
| 3494 | 3523 | ||
| 3495 | // zig fmt: off | 3524 | // zig fmt: off |
| 3496 | const is_pub = (flags & 0b0001) != 0; | 3525 | const is_pub = (flags & 0b0001) != 0; |
| 3497 | const is_exported = (flags & 0b0010) != 0; | 3526 | const export_bit = (flags & 0b0010) != 0; |
| 3498 | const has_align = (flags & 0b0100) != 0; | 3527 | const has_align = (flags & 0b0100) != 0; |
| 3499 | const has_linksection = (flags & 0b1000) != 0; | 3528 | const has_linksection = (flags & 0b1000) != 0; |
| 3500 | // zig fmt: on | 3529 | // zig fmt: on |
| ... | @@ -3509,7 +3538,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi | ... | @@ -3509,7 +3538,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi |
| 3509 | var is_named_test = false; | 3538 | var is_named_test = false; |
| 3510 | const decl_name: [:0]const u8 = switch (decl_name_index) { | 3539 | const decl_name: [:0]const u8 = switch (decl_name_index) { |
| 3511 | 0 => name: { | 3540 | 0 => name: { |
| 3512 | if (is_exported) { | 3541 | if (export_bit) { |
| 3513 | const i = iter.usingnamespace_index; | 3542 | const i = iter.usingnamespace_index; |
| 3514 | iter.usingnamespace_index += 1; | 3543 | iter.usingnamespace_index += 1; |
| 3515 | break :name try std.fmt.allocPrintZ(gpa, "usingnamespace_{d}", .{i}); | 3544 | break :name try std.fmt.allocPrintZ(gpa, "usingnamespace_{d}", .{i}); |
| ... | @@ -3535,11 +3564,17 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi | ... | @@ -3535,11 +3564,17 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi |
| 3535 | } | 3564 | } |
| 3536 | }, | 3565 | }, |
| 3537 | }; | 3566 | }; |
| 3567 | const is_exported = export_bit and decl_name_index != 0; | ||
| 3568 | const is_usingnamespace = export_bit and decl_name_index == 0; | ||
| 3569 | if (is_usingnamespace) try namespace.usingnamespace_set.ensureUnusedCapacity(gpa, 1); | ||
| 3538 | 3570 | ||
| 3539 | // We create a Decl for it regardless of analysis status. | 3571 | // We create a Decl for it regardless of analysis status. |
| 3540 | const gop = try namespace.decls.getOrPut(gpa, decl_name); | 3572 | const gop = try namespace.decls.getOrPut(gpa, decl_name); |
| 3541 | if (!gop.found_existing) { | 3573 | if (!gop.found_existing) { |
| 3542 | const new_decl = try mod.allocateNewDecl(namespace, decl_node); | 3574 | const new_decl = try mod.allocateNewDecl(namespace, decl_node); |
| 3575 | if (is_usingnamespace) { | ||
| 3576 | namespace.usingnamespace_set.putAssumeCapacity(new_decl, is_pub); | ||
| 3577 | } | ||
| 3543 | log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace }); | 3578 | log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace }); |
| 3544 | new_decl.src_line = line; | 3579 | new_decl.src_line = line; |
| 3545 | new_decl.name = decl_name; | 3580 | new_decl.name = decl_name; |
| ... | @@ -3548,7 +3583,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi | ... | @@ -3548,7 +3583,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi |
| 3548 | // test decls if in test mode, get analyzed. | 3583 | // test decls if in test mode, get analyzed. |
| 3549 | const decl_pkg = namespace.file_scope.pkg; | 3584 | const decl_pkg = namespace.file_scope.pkg; |
| 3550 | const want_analysis = is_exported or switch (decl_name_index) { | 3585 | const want_analysis = is_exported or switch (decl_name_index) { |
| 3551 | 0 => true, // comptime decl | 3586 | 0 => true, // comptime or usingnamespace decl |
| 3552 | 1 => blk: { | 3587 | 1 => blk: { |
| 3553 | // test decl with no name. Skip the part where we check against | 3588 | // test decl with no name. Skip the part where we check against |
| 3554 | // the test name filter. | 3589 | // the test name filter. |
| ... | @@ -3571,6 +3606,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi | ... | @@ -3571,6 +3606,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi |
| 3571 | } | 3606 | } |
| 3572 | new_decl.is_pub = is_pub; | 3607 | new_decl.is_pub = is_pub; |
| 3573 | new_decl.is_exported = is_exported; | 3608 | new_decl.is_exported = is_exported; |
| 3609 | new_decl.is_usingnamespace = is_usingnamespace; | ||
| 3574 | new_decl.has_align = has_align; | 3610 | new_decl.has_align = has_align; |
| 3575 | new_decl.has_linksection = has_linksection; | 3611 | new_decl.has_linksection = has_linksection; |
| 3576 | new_decl.zir_decl_index = @intCast(u32, decl_sub_index); | 3612 | new_decl.zir_decl_index = @intCast(u32, decl_sub_index); |
| ... | @@ -3587,6 +3623,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi | ... | @@ -3587,6 +3623,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi |
| 3587 | 3623 | ||
| 3588 | decl.is_pub = is_pub; | 3624 | decl.is_pub = is_pub; |
| 3589 | decl.is_exported = is_exported; | 3625 | decl.is_exported = is_exported; |
| 3626 | decl.is_usingnamespace = is_usingnamespace; | ||
| 3590 | decl.has_align = has_align; | 3627 | decl.has_align = has_align; |
| 3591 | decl.has_linksection = has_linksection; | 3628 | decl.has_linksection = has_linksection; |
| 3592 | decl.zir_decl_index = @intCast(u32, decl_sub_index); | 3629 | decl.zir_decl_index = @intCast(u32, decl_sub_index); |
| ... | @@ -3979,6 +4016,7 @@ pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast. | ... | @@ -3979,6 +4016,7 @@ pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast. |
| 3979 | .has_linksection = false, | 4016 | .has_linksection = false, |
| 3980 | .has_align = false, | 4017 | .has_align = false, |
| 3981 | .alive = false, | 4018 | .alive = false, |
| 4019 | .is_usingnamespace = false, | ||
| 3982 | }; | 4020 | }; |
| 3983 | return new_decl; | 4021 | return new_decl; |
| 3984 | } | 4022 | } |
src/Sema.zig+99-16| ... | @@ -58,6 +58,9 @@ comptime_args_fn_inst: Zir.Inst.Index = 0, | ... | @@ -58,6 +58,9 @@ comptime_args_fn_inst: Zir.Inst.Index = 0, |
| 58 | /// extra hash table lookup in the `monomorphed_funcs` set. | 58 | /// extra hash table lookup in the `monomorphed_funcs` set. |
| 59 | /// Sema will set this to null when it takes ownership. | 59 | /// Sema will set this to null when it takes ownership. |
| 60 | preallocated_new_func: ?*Module.Fn = null, | 60 | preallocated_new_func: ?*Module.Fn = null, |
| 61 | /// Collects struct, union, enum, and opaque decls which need to have their | ||
| 62 | /// fields resolved before this Sema is deinitialized. | ||
| 63 | types_pending_resolution: std.ArrayListUnmanaged(Type) = .{}, | ||
| 61 | 64 | ||
| 62 | const std = @import("std"); | 65 | const std = @import("std"); |
| 63 | const mem = std.mem; | 66 | const mem = std.mem; |
| ... | @@ -90,6 +93,7 @@ pub fn deinit(sema: *Sema) void { | ... | @@ -90,6 +93,7 @@ pub fn deinit(sema: *Sema) void { |
| 90 | sema.air_values.deinit(gpa); | 93 | sema.air_values.deinit(gpa); |
| 91 | sema.inst_map.deinit(gpa); | 94 | sema.inst_map.deinit(gpa); |
| 92 | sema.decl_val_table.deinit(gpa); | 95 | sema.decl_val_table.deinit(gpa); |
| 96 | sema.types_pending_resolution.deinit(gpa); | ||
| 93 | sema.* = undefined; | 97 | sema.* = undefined; |
| 94 | } | 98 | } |
| 95 | 99 | ||
| ... | @@ -908,7 +912,9 @@ fn zirStructDecl( | ... | @@ -908,7 +912,9 @@ fn zirStructDecl( |
| 908 | &struct_obj.namespace, new_decl, new_decl.name, | 912 | &struct_obj.namespace, new_decl, new_decl.name, |
| 909 | }); | 913 | }); |
| 910 | try sema.analyzeStructDecl(new_decl, inst, struct_obj); | 914 | try sema.analyzeStructDecl(new_decl, inst, struct_obj); |
| 915 | try sema.types_pending_resolution.ensureUnusedCapacity(sema.gpa, 1); | ||
| 911 | try new_decl.finalizeNewArena(&new_decl_arena); | 916 | try new_decl.finalizeNewArena(&new_decl_arena); |
| 917 | sema.types_pending_resolution.appendAssumeCapacity(struct_ty); | ||
| 912 | return sema.analyzeDeclVal(block, src, new_decl); | 918 | return sema.analyzeDeclVal(block, src, new_decl); |
| 913 | } | 919 | } |
| 914 | 920 | ||
| ... | @@ -1198,7 +1204,9 @@ fn zirUnionDecl( | ... | @@ -1198,7 +1204,9 @@ fn zirUnionDecl( |
| 1198 | 1204 | ||
| 1199 | _ = try sema.mod.scanNamespace(&union_obj.namespace, extra_index, decls_len, new_decl); | 1205 | _ = try sema.mod.scanNamespace(&union_obj.namespace, extra_index, decls_len, new_decl); |
| 1200 | 1206 | ||
| 1207 | try sema.types_pending_resolution.ensureUnusedCapacity(sema.gpa, 1); | ||
| 1201 | try new_decl.finalizeNewArena(&new_decl_arena); | 1208 | try new_decl.finalizeNewArena(&new_decl_arena); |
| 1209 | sema.types_pending_resolution.appendAssumeCapacity(union_ty); | ||
| 1202 | return sema.analyzeDeclVal(block, src, new_decl); | 1210 | return sema.analyzeDeclVal(block, src, new_decl); |
| 1203 | } | 1211 | } |
| 1204 | 1212 | ||
| ... | @@ -2324,42 +2332,105 @@ fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -2324,42 +2332,105 @@ fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr |
| 2324 | } | 2332 | } |
| 2325 | 2333 | ||
| 2326 | fn lookupIdentifier(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, name: []const u8) !*Decl { | 2334 | fn lookupIdentifier(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, name: []const u8) !*Decl { |
| 2327 | // TODO emit a compile error if more than one decl would be matched. | ||
| 2328 | var namespace = sema.namespace; | 2335 | var namespace = sema.namespace; |
| 2329 | while (true) { | 2336 | while (true) { |
| 2330 | if (try sema.lookupInNamespace(namespace, name)) |decl| { | 2337 | if (try sema.lookupInNamespace(block, src, namespace, name, false)) |decl| { |
| 2331 | return decl; | 2338 | return decl; |
| 2332 | } | 2339 | } |
| 2333 | namespace = namespace.parent orelse break; | 2340 | namespace = namespace.parent orelse break; |
| 2334 | } | 2341 | } |
| 2335 | return sema.mod.fail(&block.base, src, "use of undeclared identifier '{s}'", .{name}); | 2342 | unreachable; // AstGen detects use of undeclared identifier errors. |
| 2336 | } | 2343 | } |
| 2337 | 2344 | ||
| 2338 | /// This looks up a member of a specific namespace. It is affected by `usingnamespace` but | 2345 | /// This looks up a member of a specific namespace. It is affected by `usingnamespace` but |
| 2339 | /// only for ones in the specified namespace. | 2346 | /// only for ones in the specified namespace. |
| 2340 | fn lookupInNamespace( | 2347 | fn lookupInNamespace( |
| 2341 | sema: *Sema, | 2348 | sema: *Sema, |
| 2349 | block: *Scope.Block, | ||
| 2350 | src: LazySrcLoc, | ||
| 2342 | namespace: *Scope.Namespace, | 2351 | namespace: *Scope.Namespace, |
| 2343 | ident_name: []const u8, | 2352 | ident_name: []const u8, |
| 2353 | observe_usingnamespace: bool, | ||
| 2344 | ) CompileError!?*Decl { | 2354 | ) CompileError!?*Decl { |
| 2355 | const mod = sema.mod; | ||
| 2356 | |||
| 2345 | const namespace_decl = namespace.getDecl(); | 2357 | const namespace_decl = namespace.getDecl(); |
| 2346 | if (namespace_decl.analysis == .file_failure) { | 2358 | if (namespace_decl.analysis == .file_failure) { |
| 2347 | try sema.mod.declareDeclDependency(sema.owner_decl, namespace_decl); | 2359 | try mod.declareDeclDependency(sema.owner_decl, namespace_decl); |
| 2348 | return error.AnalysisFail; | 2360 | return error.AnalysisFail; |
| 2349 | } | 2361 | } |
| 2350 | 2362 | ||
| 2351 | // TODO implement usingnamespace | 2363 | if (observe_usingnamespace and namespace.usingnamespace_set.count() != 0) { |
| 2352 | if (namespace.decls.get(ident_name)) |decl| { | 2364 | const src_file = block.src_decl.namespace.file_scope; |
| 2353 | try sema.mod.declareDeclDependency(sema.owner_decl, decl); | 2365 | |
| 2366 | const gpa = sema.gpa; | ||
| 2367 | var checked_namespaces: std.AutoArrayHashMapUnmanaged(*Scope.Namespace, void) = .{}; | ||
| 2368 | defer checked_namespaces.deinit(gpa); | ||
| 2369 | |||
| 2370 | // Keep track of name conflicts for error notes. | ||
| 2371 | var candidates: std.ArrayListUnmanaged(*Decl) = .{}; | ||
| 2372 | defer candidates.deinit(gpa); | ||
| 2373 | |||
| 2374 | try checked_namespaces.put(gpa, namespace, {}); | ||
| 2375 | var check_i: usize = 0; | ||
| 2376 | |||
| 2377 | while (check_i < checked_namespaces.count()) : (check_i += 1) { | ||
| 2378 | const check_ns = checked_namespaces.keys()[check_i]; | ||
| 2379 | if (check_ns.decls.get(ident_name)) |decl| { | ||
| 2380 | // Skip decls which are not marked pub, which are in a different | ||
| 2381 | // file than the `a.b`/`@hasDecl` syntax. | ||
| 2382 | if (decl.is_pub or src_file == decl.namespace.file_scope) { | ||
| 2383 | try candidates.append(gpa, decl); | ||
| 2384 | } | ||
| 2385 | } | ||
| 2386 | var it = check_ns.usingnamespace_set.iterator(); | ||
| 2387 | while (it.next()) |entry| { | ||
| 2388 | const sub_usingnamespace_decl = entry.key_ptr.*; | ||
| 2389 | const sub_is_pub = entry.value_ptr.*; | ||
| 2390 | if (!sub_is_pub and src_file != sub_usingnamespace_decl.namespace.file_scope) { | ||
| 2391 | // Skip usingnamespace decls which are not marked pub, which are in | ||
| 2392 | // a different file than the `a.b`/`@hasDecl` syntax. | ||
| 2393 | continue; | ||
| 2394 | } | ||
| 2395 | try sema.ensureDeclAnalyzed(sub_usingnamespace_decl); | ||
| 2396 | const ns_ty = sub_usingnamespace_decl.val.castTag(.ty).?.data; | ||
| 2397 | const sub_ns = ns_ty.getNamespace().?; | ||
| 2398 | try checked_namespaces.put(gpa, sub_ns, {}); | ||
| 2399 | } | ||
| 2400 | } | ||
| 2401 | |||
| 2402 | switch (candidates.items.len) { | ||
| 2403 | 0 => {}, | ||
| 2404 | 1 => { | ||
| 2405 | const decl = candidates.items[0]; | ||
| 2406 | try mod.declareDeclDependency(sema.owner_decl, decl); | ||
| 2407 | return decl; | ||
| 2408 | }, | ||
| 2409 | else => { | ||
| 2410 | const msg = msg: { | ||
| 2411 | const msg = try mod.errMsg(&block.base, src, "ambiguous reference", .{}); | ||
| 2412 | errdefer msg.destroy(gpa); | ||
| 2413 | for (candidates.items) |candidate| { | ||
| 2414 | const src_loc = candidate.srcLoc(); | ||
| 2415 | try mod.errNoteNonLazy(src_loc, msg, "declared here", .{}); | ||
| 2416 | } | ||
| 2417 | break :msg msg; | ||
| 2418 | }; | ||
| 2419 | return mod.failWithOwnedErrorMsg(&block.base, msg); | ||
| 2420 | }, | ||
| 2421 | } | ||
| 2422 | } else if (namespace.decls.get(ident_name)) |decl| { | ||
| 2423 | try mod.declareDeclDependency(sema.owner_decl, decl); | ||
| 2354 | return decl; | 2424 | return decl; |
| 2355 | } | 2425 | } |
| 2426 | |||
| 2356 | log.debug("{*} ({s}) depends on non-existence of '{s}' in {*} ({s})", .{ | 2427 | log.debug("{*} ({s}) depends on non-existence of '{s}' in {*} ({s})", .{ |
| 2357 | sema.owner_decl, sema.owner_decl.name, ident_name, namespace_decl, namespace_decl.name, | 2428 | sema.owner_decl, sema.owner_decl.name, ident_name, namespace_decl, namespace_decl.name, |
| 2358 | }); | 2429 | }); |
| 2359 | // TODO This dependency is too strong. Really, it should only be a dependency | 2430 | // TODO This dependency is too strong. Really, it should only be a dependency |
| 2360 | // on the non-existence of `ident_name` in the namespace. We can lessen the number of | 2431 | // on the non-existence of `ident_name` in the namespace. We can lessen the number of |
| 2361 | // outdated declarations by making this dependency more sophisticated. | 2432 | // outdated declarations by making this dependency more sophisticated. |
| 2362 | try sema.mod.declareDeclDependency(sema.owner_decl, namespace_decl); | 2433 | try mod.declareDeclDependency(sema.owner_decl, namespace_decl); |
| 2363 | return null; | 2434 | return null; |
| 2364 | } | 2435 | } |
| 2365 | 2436 | ||
| ... | @@ -2727,10 +2798,7 @@ fn analyzeCall( | ... | @@ -2727,10 +2798,7 @@ fn analyzeCall( |
| 2727 | // we need to resolve the field type expressions right here, right now, while | 2798 | // we need to resolve the field type expressions right here, right now, while |
| 2728 | // the child `Sema` is still available, with the AIR instruction map intact, | 2799 | // the child `Sema` is still available, with the AIR instruction map intact, |
| 2729 | // because the field type expressions may reference into it. | 2800 | // because the field type expressions may reference into it. |
| 2730 | if (sema.typeOf(result).zigTypeTag() == .Type) { | 2801 | try sema.resolvePendingTypes(&child_block); |
| 2731 | const ty = try sema.analyzeAsType(&child_block, call_src, result); | ||
| 2732 | try sema.resolveDeclFields(&child_block, call_src, ty); | ||
| 2733 | } | ||
| 2734 | } | 2802 | } |
| 2735 | 2803 | ||
| 2736 | break :res2 result; | 2804 | break :res2 result; |
| ... | @@ -5332,6 +5400,7 @@ fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr | ... | @@ -5332,6 +5400,7 @@ fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr |
| 5332 | fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { | 5400 | fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 5333 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; | 5401 | const inst_data = sema.code.instructions.items(.data)[inst].pl_node; |
| 5334 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; | 5402 | const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; |
| 5403 | const src = inst_data.src(); | ||
| 5335 | const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; | 5404 | const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; |
| 5336 | const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; | 5405 | const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; |
| 5337 | const container_type = try sema.resolveType(block, lhs_src, extra.lhs); | 5406 | const container_type = try sema.resolveType(block, lhs_src, extra.lhs); |
| ... | @@ -5344,7 +5413,7 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr | ... | @@ -5344,7 +5413,7 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr |
| 5344 | "expected struct, enum, union, or opaque, found '{}'", | 5413 | "expected struct, enum, union, or opaque, found '{}'", |
| 5345 | .{container_type}, | 5414 | .{container_type}, |
| 5346 | ); | 5415 | ); |
| 5347 | if (try sema.lookupInNamespace(namespace, decl_name)) |decl| { | 5416 | if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl| { |
| 5348 | if (decl.is_pub or decl.namespace.file_scope == block.base.namespace().file_scope) { | 5417 | if (decl.is_pub or decl.namespace.file_scope == block.base.namespace().file_scope) { |
| 5349 | return Air.Inst.Ref.bool_true; | 5418 | return Air.Inst.Ref.bool_true; |
| 5350 | } | 5419 | } |
| ... | @@ -8203,7 +8272,7 @@ fn namespaceLookup( | ... | @@ -8203,7 +8272,7 @@ fn namespaceLookup( |
| 8203 | ) CompileError!?*Decl { | 8272 | ) CompileError!?*Decl { |
| 8204 | const mod = sema.mod; | 8273 | const mod = sema.mod; |
| 8205 | const gpa = sema.gpa; | 8274 | const gpa = sema.gpa; |
| 8206 | if (try sema.lookupInNamespace(namespace, decl_name)) |decl| { | 8275 | if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl| { |
| 8207 | if (!decl.is_pub and decl.namespace.file_scope != block.getFileScope()) { | 8276 | if (!decl.is_pub and decl.namespace.file_scope != block.getFileScope()) { |
| 8208 | const msg = msg: { | 8277 | const msg = msg: { |
| 8209 | const msg = try mod.errMsg(&block.base, src, "'{s}' is not marked 'pub'", .{ | 8278 | const msg = try mod.errMsg(&block.base, src, "'{s}' is not marked 'pub'", .{ |
| ... | @@ -8919,8 +8988,7 @@ fn analyzeDeclVal( | ... | @@ -8919,8 +8988,7 @@ fn analyzeDeclVal( |
| 8919 | return result; | 8988 | return result; |
| 8920 | } | 8989 | } |
| 8921 | 8990 | ||
| 8922 | fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { | 8991 | fn ensureDeclAnalyzed(sema: *Sema, decl: *Decl) CompileError!void { |
| 8923 | try sema.mod.declareDeclDependency(sema.owner_decl, decl); | ||
| 8924 | sema.mod.ensureDeclAnalyzed(decl) catch |err| { | 8992 | sema.mod.ensureDeclAnalyzed(decl) catch |err| { |
| 8925 | if (sema.owner_func) |owner_func| { | 8993 | if (sema.owner_func) |owner_func| { |
| 8926 | owner_func.state = .dependency_failure; | 8994 | owner_func.state = .dependency_failure; |
| ... | @@ -8929,6 +8997,11 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { | ... | @@ -8929,6 +8997,11 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { |
| 8929 | } | 8997 | } |
| 8930 | return err; | 8998 | return err; |
| 8931 | }; | 8999 | }; |
| 9000 | } | ||
| 9001 | |||
| 9002 | fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref { | ||
| 9003 | try sema.mod.declareDeclDependency(sema.owner_decl, decl); | ||
| 9004 | try sema.ensureDeclAnalyzed(decl); | ||
| 8932 | 9005 | ||
| 8933 | const decl_tv = try decl.typedValue(); | 9006 | const decl_tv = try decl.typedValue(); |
| 8934 | if (decl_tv.val.castTag(.variable)) |payload| { | 9007 | if (decl_tv.val.castTag(.variable)) |payload| { |
| ... | @@ -9560,6 +9633,16 @@ pub fn resolveTypeLayout( | ... | @@ -9560,6 +9633,16 @@ pub fn resolveTypeLayout( |
| 9560 | } | 9633 | } |
| 9561 | } | 9634 | } |
| 9562 | 9635 | ||
| 9636 | pub fn resolvePendingTypes(sema: *Sema, block: *Scope.Block) !void { | ||
| 9637 | for (sema.types_pending_resolution.items) |ty| { | ||
| 9638 | // If an error happens resolving the fields of a struct, it will be marked | ||
| 9639 | // invalid and a proper compile error set up. But we should still look at the | ||
| 9640 | // other types pending resolution. | ||
| 9641 | const src: LazySrcLoc = .{ .node_offset = 0 }; | ||
| 9642 | sema.resolveDeclFields(block, src, ty) catch continue; | ||
| 9643 | } | ||
| 9644 | } | ||
| 9645 | |||
| 9563 | /// `sema` and `block` are expected to be the same ones used for the `Decl`. | 9646 | /// `sema` and `block` are expected to be the same ones used for the `Decl`. |
| 9564 | pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) !void { | 9647 | pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) !void { |
| 9565 | switch (ty.tag()) { | 9648 | switch (ty.tag()) { |
src/codegen.zig+13-13| ... | @@ -899,7 +899,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -899,7 +899,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 899 | fn dbgSetPrologueEnd(self: *Self) InnerError!void { | 899 | fn dbgSetPrologueEnd(self: *Self) InnerError!void { |
| 900 | switch (self.debug_output) { | 900 | switch (self.debug_output) { |
| 901 | .dwarf => |dbg_out| { | 901 | .dwarf => |dbg_out| { |
| 902 | try dbg_out.dbg_line.append(DW.LNS_set_prologue_end); | 902 | try dbg_out.dbg_line.append(DW.LNS.set_prologue_end); |
| 903 | try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column); | 903 | try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column); |
| 904 | }, | 904 | }, |
| 905 | .none => {}, | 905 | .none => {}, |
| ... | @@ -909,7 +909,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -909,7 +909,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 909 | fn dbgSetEpilogueBegin(self: *Self) InnerError!void { | 909 | fn dbgSetEpilogueBegin(self: *Self) InnerError!void { |
| 910 | switch (self.debug_output) { | 910 | switch (self.debug_output) { |
| 911 | .dwarf => |dbg_out| { | 911 | .dwarf => |dbg_out| { |
| 912 | try dbg_out.dbg_line.append(DW.LNS_set_epilogue_begin); | 912 | try dbg_out.dbg_line.append(DW.LNS.set_epilogue_begin); |
| 913 | try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column); | 913 | try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column); |
| 914 | }, | 914 | }, |
| 915 | .none => {}, | 915 | .none => {}, |
| ... | @@ -925,13 +925,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -925,13 +925,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 925 | // It lets you emit single-byte opcodes that add different numbers to | 925 | // It lets you emit single-byte opcodes that add different numbers to |
| 926 | // both the PC and the line number at the same time. | 926 | // both the PC and the line number at the same time. |
| 927 | try dbg_out.dbg_line.ensureUnusedCapacity(11); | 927 | try dbg_out.dbg_line.ensureUnusedCapacity(11); |
| 928 | dbg_out.dbg_line.appendAssumeCapacity(DW.LNS_advance_pc); | 928 | dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.advance_pc); |
| 929 | leb128.writeULEB128(dbg_out.dbg_line.writer(), delta_pc) catch unreachable; | 929 | leb128.writeULEB128(dbg_out.dbg_line.writer(), delta_pc) catch unreachable; |
| 930 | if (delta_line != 0) { | 930 | if (delta_line != 0) { |
| 931 | dbg_out.dbg_line.appendAssumeCapacity(DW.LNS_advance_line); | 931 | dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.advance_line); |
| 932 | leb128.writeILEB128(dbg_out.dbg_line.writer(), delta_line) catch unreachable; | 932 | leb128.writeILEB128(dbg_out.dbg_line.writer(), delta_line) catch unreachable; |
| 933 | } | 933 | } |
| 934 | dbg_out.dbg_line.appendAssumeCapacity(DW.LNS_copy); | 934 | dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.copy); |
| 935 | }, | 935 | }, |
| 936 | .none => {}, | 936 | .none => {}, |
| 937 | } | 937 | } |
| ... | @@ -1010,7 +1010,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -1010,7 +1010,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 1010 | .dwarf => |dbg_out| { | 1010 | .dwarf => |dbg_out| { |
| 1011 | assert(ty.hasCodeGenBits()); | 1011 | assert(ty.hasCodeGenBits()); |
| 1012 | const index = dbg_out.dbg_info.items.len; | 1012 | const index = dbg_out.dbg_info.items.len; |
| 1013 | try dbg_out.dbg_info.resize(index + 4); // DW.AT_type, DW.FORM_ref4 | 1013 | try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4 |
| 1014 | 1014 | ||
| 1015 | const gop = try dbg_out.dbg_info_type_relocs.getOrPut(self.gpa, ty); | 1015 | const gop = try dbg_out.dbg_info_type_relocs.getOrPut(self.gpa, ty); |
| 1016 | if (!gop.found_existing) { | 1016 | if (!gop.found_existing) { |
| ... | @@ -2438,13 +2438,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -2438,13 +2438,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2438 | .dwarf => |dbg_out| { | 2438 | .dwarf => |dbg_out| { |
| 2439 | try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 3); | 2439 | try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 3); |
| 2440 | dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter); | 2440 | dbg_out.dbg_info.appendAssumeCapacity(link.File.Elf.abbrev_parameter); |
| 2441 | dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT_location, DW.FORM_exprloc | 2441 | dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc |
| 2442 | 1, // ULEB128 dwarf expression length | 2442 | 1, // ULEB128 dwarf expression length |
| 2443 | reg.dwarfLocOp(), | 2443 | reg.dwarfLocOp(), |
| 2444 | }); | 2444 | }); |
| 2445 | try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 5 + name_with_null.len); | 2445 | try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 5 + name_with_null.len); |
| 2446 | try self.addDbgInfoTypeReloc(ty); // DW.AT_type, DW.FORM_ref4 | 2446 | try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4 |
| 2447 | dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT_name, DW.FORM_string | 2447 | dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string |
| 2448 | }, | 2448 | }, |
| 2449 | .none => {}, | 2449 | .none => {}, |
| 2450 | } | 2450 | } |
| ... | @@ -2467,15 +2467,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { | ... | @@ -2467,15 +2467,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type { |
| 2467 | var counting_writer = std.io.countingWriter(std.io.null_writer); | 2467 | var counting_writer = std.io.countingWriter(std.io.null_writer); |
| 2468 | leb128.writeILEB128(counting_writer.writer(), adjusted_stack_offset) catch unreachable; | 2468 | leb128.writeILEB128(counting_writer.writer(), adjusted_stack_offset) catch unreachable; |
| 2469 | 2469 | ||
| 2470 | // DW.AT_location, DW.FORM_exprloc | 2470 | // DW.AT.location, DW.FORM.exprloc |
| 2471 | // ULEB128 dwarf expression length | 2471 | // ULEB128 dwarf expression length |
| 2472 | try leb128.writeULEB128(dbg_out.dbg_info.writer(), counting_writer.bytes_written + 1); | 2472 | try leb128.writeULEB128(dbg_out.dbg_info.writer(), counting_writer.bytes_written + 1); |
| 2473 | try dbg_out.dbg_info.append(DW.OP_breg11); | 2473 | try dbg_out.dbg_info.append(DW.OP.breg11); |
| 2474 | try leb128.writeILEB128(dbg_out.dbg_info.writer(), adjusted_stack_offset); | 2474 | try leb128.writeILEB128(dbg_out.dbg_info.writer(), adjusted_stack_offset); |
| 2475 | 2475 | ||
| 2476 | try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 5 + name_with_null.len); | 2476 | try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 5 + name_with_null.len); |
| 2477 | try self.addDbgInfoTypeReloc(ty); // DW.AT_type, DW.FORM_ref4 | 2477 | try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4 |
| 2478 | dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT_name, DW.FORM_string | 2478 | dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT.name, DW.FORM.string |
| 2479 | }, | 2479 | }, |
| 2480 | else => {}, | 2480 | else => {}, |
| 2481 | } | 2481 | } |
src/codegen/aarch64.zig+1-1| ... | @@ -52,7 +52,7 @@ pub const Register = enum(u6) { | ... | @@ -52,7 +52,7 @@ pub const Register = enum(u6) { |
| 52 | } | 52 | } |
| 53 | 53 | ||
| 54 | pub fn dwarfLocOp(self: Register) u8 { | 54 | pub fn dwarfLocOp(self: Register) u8 { |
| 55 | return @as(u8, self.id()) + DW.OP_reg0; | 55 | return @as(u8, self.id()) + DW.OP.reg0; |
| 56 | } | 56 | } |
| 57 | }; | 57 | }; |
| 58 | 58 |
src/codegen/arm.zig+1-1| ... | @@ -170,7 +170,7 @@ pub const Register = enum(u5) { | ... | @@ -170,7 +170,7 @@ pub const Register = enum(u5) { |
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | pub fn dwarfLocOp(self: Register) u8 { | 172 | pub fn dwarfLocOp(self: Register) u8 { |
| 173 | return @as(u8, self.id()) + DW.OP_reg0; | 173 | return @as(u8, self.id()) + DW.OP.reg0; |
| 174 | } | 174 | } |
| 175 | }; | 175 | }; |
| 176 | 176 |
src/codegen/riscv64.zig+2-2| ... | @@ -390,7 +390,7 @@ pub const RawRegister = enum(u5) { | ... | @@ -390,7 +390,7 @@ pub const RawRegister = enum(u5) { |
| 390 | x24, x25, x26, x27, x28, x29, x30, x31, | 390 | x24, x25, x26, x27, x28, x29, x30, x31, |
| 391 | 391 | ||
| 392 | pub fn dwarfLocOp(reg: RawRegister) u8 { | 392 | pub fn dwarfLocOp(reg: RawRegister) u8 { |
| 393 | return @enumToInt(reg) + DW.OP_reg0; | 393 | return @enumToInt(reg) + DW.OP.reg0; |
| 394 | } | 394 | } |
| 395 | }; | 395 | }; |
| 396 | 396 | ||
| ... | @@ -424,7 +424,7 @@ pub const Register = enum(u5) { | ... | @@ -424,7 +424,7 @@ pub const Register = enum(u5) { |
| 424 | } | 424 | } |
| 425 | 425 | ||
| 426 | pub fn dwarfLocOp(reg: Register) u8 { | 426 | pub fn dwarfLocOp(reg: Register) u8 { |
| 427 | return @as(u8, @enumToInt(reg)) + DW.OP_reg0; | 427 | return @as(u8, @enumToInt(reg)) + DW.OP.reg0; |
| 428 | } | 428 | } |
| 429 | }; | 429 | }; |
| 430 | 430 |
src/codegen/x86.zig+8-8| ... | @@ -59,14 +59,14 @@ pub const Register = enum(u8) { | ... | @@ -59,14 +59,14 @@ pub const Register = enum(u8) { |
| 59 | 59 | ||
| 60 | pub fn dwarfLocOp(reg: Register) u8 { | 60 | pub fn dwarfLocOp(reg: Register) u8 { |
| 61 | return switch (reg.to32()) { | 61 | return switch (reg.to32()) { |
| 62 | .eax => DW.OP_reg0, | 62 | .eax => DW.OP.reg0, |
| 63 | .ecx => DW.OP_reg1, | 63 | .ecx => DW.OP.reg1, |
| 64 | .edx => DW.OP_reg2, | 64 | .edx => DW.OP.reg2, |
| 65 | .ebx => DW.OP_reg3, | 65 | .ebx => DW.OP.reg3, |
| 66 | .esp => DW.OP_reg4, | 66 | .esp => DW.OP.reg4, |
| 67 | .ebp => DW.OP_reg5, | 67 | .ebp => DW.OP.reg5, |
| 68 | .esi => DW.OP_reg6, | 68 | .esi => DW.OP.reg6, |
| 69 | .edi => DW.OP_reg7, | 69 | .edi => DW.OP.reg7, |
| 70 | else => unreachable, | 70 | else => unreachable, |
| 71 | }; | 71 | }; |
| 72 | } | 72 | } |
src/codegen/x86_64.zig+17-17| ... | @@ -115,23 +115,23 @@ pub const Register = enum(u8) { | ... | @@ -115,23 +115,23 @@ pub const Register = enum(u8) { |
| 115 | 115 | ||
| 116 | pub fn dwarfLocOp(self: Register) u8 { | 116 | pub fn dwarfLocOp(self: Register) u8 { |
| 117 | return switch (self.to64()) { | 117 | return switch (self.to64()) { |
| 118 | .rax => DW.OP_reg0, | 118 | .rax => DW.OP.reg0, |
| 119 | .rdx => DW.OP_reg1, | 119 | .rdx => DW.OP.reg1, |
| 120 | .rcx => DW.OP_reg2, | 120 | .rcx => DW.OP.reg2, |
| 121 | .rbx => DW.OP_reg3, | 121 | .rbx => DW.OP.reg3, |
| 122 | .rsi => DW.OP_reg4, | 122 | .rsi => DW.OP.reg4, |
| 123 | .rdi => DW.OP_reg5, | 123 | .rdi => DW.OP.reg5, |
| 124 | .rbp => DW.OP_reg6, | 124 | .rbp => DW.OP.reg6, |
| 125 | .rsp => DW.OP_reg7, | 125 | .rsp => DW.OP.reg7, |
| 126 | 126 | ||
| 127 | .r8 => DW.OP_reg8, | 127 | .r8 => DW.OP.reg8, |
| 128 | .r9 => DW.OP_reg9, | 128 | .r9 => DW.OP.reg9, |
| 129 | .r10 => DW.OP_reg10, | 129 | .r10 => DW.OP.reg10, |
| 130 | .r11 => DW.OP_reg11, | 130 | .r11 => DW.OP.reg11, |
| 131 | .r12 => DW.OP_reg12, | 131 | .r12 => DW.OP.reg12, |
| 132 | .r13 => DW.OP_reg13, | 132 | .r13 => DW.OP.reg13, |
| 133 | .r14 => DW.OP_reg14, | 133 | .r14 => DW.OP.reg14, |
| 134 | .r15 => DW.OP_reg15, | 134 | .r15 => DW.OP.reg15, |
| 135 | 135 | ||
| 136 | else => unreachable, | 136 | else => unreachable, |
| 137 | }; | 137 | }; |
src/link.zig+1-1| ... | @@ -179,7 +179,7 @@ pub const File = struct { | ... | @@ -179,7 +179,7 @@ pub const File = struct { |
| 179 | /// This is where the .debug_info tag for the type is. | 179 | /// This is where the .debug_info tag for the type is. |
| 180 | off: u32, | 180 | off: u32, |
| 181 | /// Offset from `TextBlock.dbg_info_off` (the buffer that is local to a Decl). | 181 | /// Offset from `TextBlock.dbg_info_off` (the buffer that is local to a Decl). |
| 182 | /// List of DW.AT_type / DW.FORM_ref4 that points to the type. | 182 | /// List of DW.AT.type / DW.FORM.ref4 that points to the type. |
| 183 | relocs: std.ArrayListUnmanaged(u32), | 183 | relocs: std.ArrayListUnmanaged(u32), |
| 184 | }; | 184 | }; |
| 185 | 185 |
src/link/Elf.zig+76-76| ... | @@ -772,48 +772,48 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { | ... | @@ -772,48 +772,48 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 772 | // These are LEB encoded but since the values are all less than 127 | 772 | // These are LEB encoded but since the values are all less than 127 |
| 773 | // we can simply append these bytes. | 773 | // we can simply append these bytes. |
| 774 | const abbrev_buf = [_]u8{ | 774 | const abbrev_buf = [_]u8{ |
| 775 | abbrev_compile_unit, DW.TAG_compile_unit, DW.CHILDREN_yes, // header | 775 | abbrev_compile_unit, DW.TAG.compile_unit, DW.CHILDREN.yes, // header |
| 776 | DW.AT_stmt_list, DW.FORM_sec_offset, DW.AT_low_pc, | 776 | DW.AT.stmt_list, DW.FORM.sec_offset, DW.AT.low_pc, |
| 777 | DW.FORM_addr, DW.AT_high_pc, DW.FORM_addr, | 777 | DW.FORM.addr, DW.AT.high_pc, DW.FORM.addr, |
| 778 | DW.AT_name, DW.FORM_strp, DW.AT_comp_dir, | 778 | DW.AT.name, DW.FORM.strp, DW.AT.comp_dir, |
| 779 | DW.FORM_strp, DW.AT_producer, DW.FORM_strp, | 779 | DW.FORM.strp, DW.AT.producer, DW.FORM.strp, |
| 780 | DW.AT_language, DW.FORM_data2, 0, | 780 | DW.AT.language, DW.FORM.data2, 0, |
| 781 | 0, // table sentinel | 781 | 0, // table sentinel |
| 782 | abbrev_subprogram, | 782 | abbrev_subprogram, |
| 783 | DW.TAG_subprogram, | 783 | DW.TAG.subprogram, |
| 784 | DW.CHILDREN_yes, // header | 784 | DW.CHILDREN.yes, // header |
| 785 | DW.AT_low_pc, | 785 | DW.AT.low_pc, |
| 786 | DW.FORM_addr, | 786 | DW.FORM.addr, |
| 787 | DW.AT_high_pc, | 787 | DW.AT.high_pc, |
| 788 | DW.FORM_data4, | 788 | DW.FORM.data4, |
| 789 | DW.AT_type, | 789 | DW.AT.type, |
| 790 | DW.FORM_ref4, | 790 | DW.FORM.ref4, |
| 791 | DW.AT_name, | 791 | DW.AT.name, |
| 792 | DW.FORM_string, | 792 | DW.FORM.string, |
| 793 | 0, 0, // table sentinel | 793 | 0, 0, // table sentinel |
| 794 | abbrev_subprogram_retvoid, | 794 | abbrev_subprogram_retvoid, |
| 795 | DW.TAG_subprogram, DW.CHILDREN_yes, // header | 795 | DW.TAG.subprogram, DW.CHILDREN.yes, // header |
| 796 | DW.AT_low_pc, DW.FORM_addr, | 796 | DW.AT.low_pc, DW.FORM.addr, |
| 797 | DW.AT_high_pc, DW.FORM_data4, | 797 | DW.AT.high_pc, DW.FORM.data4, |
| 798 | DW.AT_name, DW.FORM_string, | 798 | DW.AT.name, DW.FORM.string, |
| 799 | 0, | 799 | 0, |
| 800 | 0, // table sentinel | 800 | 0, // table sentinel |
| 801 | abbrev_base_type, | 801 | abbrev_base_type, |
| 802 | DW.TAG_base_type, | 802 | DW.TAG.base_type, |
| 803 | DW.CHILDREN_no, // header | 803 | DW.CHILDREN.no, // header |
| 804 | DW.AT_encoding, | 804 | DW.AT.encoding, |
| 805 | DW.FORM_data1, | 805 | DW.FORM.data1, |
| 806 | DW.AT_byte_size, | 806 | DW.AT.byte_size, |
| 807 | DW.FORM_data1, | 807 | DW.FORM.data1, |
| 808 | DW.AT_name, | 808 | DW.AT.name, |
| 809 | DW.FORM_string, 0, 0, // table sentinel | 809 | DW.FORM.string, 0, 0, // table sentinel |
| 810 | abbrev_pad1, DW.TAG_unspecified_type, DW.CHILDREN_no, // header | 810 | abbrev_pad1, DW.TAG.unspecified_type, DW.CHILDREN.no, // header |
| 811 | 0, 0, // table sentinel | 811 | 0, 0, // table sentinel |
| 812 | abbrev_parameter, | 812 | abbrev_parameter, |
| 813 | DW.TAG_formal_parameter, DW.CHILDREN_no, // header | 813 | DW.TAG.formal_parameter, DW.CHILDREN.no, // header |
| 814 | DW.AT_location, DW.FORM_exprloc, | 814 | DW.AT.location, DW.FORM.exprloc, |
| 815 | DW.AT_type, DW.FORM_ref4, | 815 | DW.AT.type, DW.FORM.ref4, |
| 816 | DW.AT_name, DW.FORM_string, | 816 | DW.AT.name, DW.FORM.string, |
| 817 | 0, | 817 | 0, |
| 818 | 0, // table sentinel | 818 | 0, // table sentinel |
| 819 | 0, | 819 | 0, |
| ... | @@ -897,7 +897,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { | ... | @@ -897,7 +897,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 897 | const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; | 897 | const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz; |
| 898 | 898 | ||
| 899 | di_buf.appendAssumeCapacity(abbrev_compile_unit); | 899 | di_buf.appendAssumeCapacity(abbrev_compile_unit); |
| 900 | self.writeDwarfAddrAssumeCapacity(&di_buf, 0); // DW.AT_stmt_list, DW.FORM_sec_offset | 900 | self.writeDwarfAddrAssumeCapacity(&di_buf, 0); // DW.AT.stmt_list, DW.FORM.sec_offset |
| 901 | self.writeDwarfAddrAssumeCapacity(&di_buf, low_pc); | 901 | self.writeDwarfAddrAssumeCapacity(&di_buf, low_pc); |
| 902 | self.writeDwarfAddrAssumeCapacity(&di_buf, high_pc); | 902 | self.writeDwarfAddrAssumeCapacity(&di_buf, high_pc); |
| 903 | self.writeDwarfAddrAssumeCapacity(&di_buf, name_strp); | 903 | self.writeDwarfAddrAssumeCapacity(&di_buf, name_strp); |
| ... | @@ -906,7 +906,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { | ... | @@ -906,7 +906,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 906 | // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number: | 906 | // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number: |
| 907 | // http://dwarfstd.org/ShowIssue.php?issue=171115.1 | 907 | // http://dwarfstd.org/ShowIssue.php?issue=171115.1 |
| 908 | // Until then we say it is C99. | 908 | // Until then we say it is C99. |
| 909 | mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG_C99, target_endian); | 909 | mem.writeInt(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG.C99, target_endian); |
| 910 | 910 | ||
| 911 | if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) { | 911 | if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) { |
| 912 | // Move the first N decls to the end to make more padding for the header. | 912 | // Move the first N decls to the end to make more padding for the header. |
| ... | @@ -1030,7 +1030,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { | ... | @@ -1030,7 +1030,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 1030 | di_buf.items.len += ptr_width_bytes; // We will come back and write this. | 1030 | di_buf.items.len += ptr_width_bytes; // We will come back and write this. |
| 1031 | const after_header_len = di_buf.items.len; | 1031 | const after_header_len = di_buf.items.len; |
| 1032 | 1032 | ||
| 1033 | const opcode_base = DW.LNS_set_isa + 1; | 1033 | const opcode_base = DW.LNS.set_isa + 1; |
| 1034 | di_buf.appendSliceAssumeCapacity(&[_]u8{ | 1034 | di_buf.appendSliceAssumeCapacity(&[_]u8{ |
| 1035 | 1, // minimum_instruction_length | 1035 | 1, // minimum_instruction_length |
| 1036 | 1, // maximum_operations_per_instruction | 1036 | 1, // maximum_operations_per_instruction |
| ... | @@ -1041,18 +1041,18 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { | ... | @@ -1041,18 +1041,18 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void { |
| 1041 | 1041 | ||
| 1042 | // Standard opcode lengths. The number of items here is based on `opcode_base`. | 1042 | // Standard opcode lengths. The number of items here is based on `opcode_base`. |
| 1043 | // The value is the number of LEB128 operands the instruction takes. | 1043 | // The value is the number of LEB128 operands the instruction takes. |
| 1044 | 0, // `DW.LNS_copy` | 1044 | 0, // `DW.LNS.copy` |
| 1045 | 1, // `DW.LNS_advance_pc` | 1045 | 1, // `DW.LNS.advance_pc` |
| 1046 | 1, // `DW.LNS_advance_line` | 1046 | 1, // `DW.LNS.advance_line` |
| 1047 | 1, // `DW.LNS_set_file` | 1047 | 1, // `DW.LNS.set_file` |
| 1048 | 1, // `DW.LNS_set_column` | 1048 | 1, // `DW.LNS.set_column` |
| 1049 | 0, // `DW.LNS_negate_stmt` | 1049 | 0, // `DW.LNS.negate_stmt` |
| 1050 | 0, // `DW.LNS_set_basic_block` | 1050 | 0, // `DW.LNS.set_basic_block` |
| 1051 | 0, // `DW.LNS_const_add_pc` | 1051 | 0, // `DW.LNS.const_add_pc` |
| 1052 | 1, // `DW.LNS_fixed_advance_pc` | 1052 | 1, // `DW.LNS.fixed_advance_pc` |
| 1053 | 0, // `DW.LNS_set_prologue_end` | 1053 | 0, // `DW.LNS.set_prologue_end` |
| 1054 | 0, // `DW.LNS_set_epilogue_begin` | 1054 | 0, // `DW.LNS.set_epilogue_begin` |
| 1055 | 1, // `DW.LNS_set_isa` | 1055 | 1, // `DW.LNS.set_isa` |
| 1056 | 0, // include_directories (none except the compilation unit cwd) | 1056 | 0, // include_directories (none except the compilation unit cwd) |
| 1057 | }); | 1057 | }); |
| 1058 | // file_names[0] | 1058 | // file_names[0] |
| ... | @@ -2053,7 +2053,7 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al | ... | @@ -2053,7 +2053,7 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al |
| 2053 | 2053 | ||
| 2054 | // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address | 2054 | // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address |
| 2055 | // range of the compilation unit. When we expand the text section, this range changes, | 2055 | // range of the compilation unit. When we expand the text section, this range changes, |
| 2056 | // so the DW_TAG_compile_unit tag of the .debug_info section becomes dirty. | 2056 | // so the DW_TAG.compile_unit tag of the .debug_info section becomes dirty. |
| 2057 | self.debug_info_header_dirty = true; | 2057 | self.debug_info_header_dirty = true; |
| 2058 | // This becomes dirty for the same reason. We could potentially make this more | 2058 | // This becomes dirty for the same reason. We could potentially make this more |
| 2059 | // fine-grained with the addition of support for more compilation units. It is planned to | 2059 | // fine-grained with the addition of support for more compilation units. It is planned to |
| ... | @@ -2303,22 +2303,22 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven | ... | @@ -2303,22 +2303,22 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven |
| 2303 | 2303 | ||
| 2304 | const ptr_width_bytes = self.ptrWidthBytes(); | 2304 | const ptr_width_bytes = self.ptrWidthBytes(); |
| 2305 | dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{ | 2305 | dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{ |
| 2306 | DW.LNS_extended_op, | 2306 | DW.LNS.extended_op, |
| 2307 | ptr_width_bytes + 1, | 2307 | ptr_width_bytes + 1, |
| 2308 | DW.LNE_set_address, | 2308 | DW.LNE.set_address, |
| 2309 | }); | 2309 | }); |
| 2310 | // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`. | 2310 | // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`. |
| 2311 | assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len); | 2311 | assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len); |
| 2312 | dbg_line_buffer.items.len += ptr_width_bytes; | 2312 | dbg_line_buffer.items.len += ptr_width_bytes; |
| 2313 | 2313 | ||
| 2314 | dbg_line_buffer.appendAssumeCapacity(DW.LNS_advance_line); | 2314 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.advance_line); |
| 2315 | // This is the "relocatable" relative line offset from the previous function's end curly | 2315 | // This is the "relocatable" relative line offset from the previous function's end curly |
| 2316 | // to this function's begin curly. | 2316 | // to this function's begin curly. |
| 2317 | assert(self.getRelocDbgLineOff() == dbg_line_buffer.items.len); | 2317 | assert(self.getRelocDbgLineOff() == dbg_line_buffer.items.len); |
| 2318 | // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later. | 2318 | // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later. |
| 2319 | leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off); | 2319 | leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off); |
| 2320 | 2320 | ||
| 2321 | dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file); | 2321 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_file); |
| 2322 | assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len); | 2322 | assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len); |
| 2323 | // Once we support more than one source file, this will have the ability to be more | 2323 | // Once we support more than one source file, this will have the ability to be more |
| 2324 | // than one possible value. | 2324 | // than one possible value. |
| ... | @@ -2327,7 +2327,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven | ... | @@ -2327,7 +2327,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven |
| 2327 | 2327 | ||
| 2328 | // Emit a line for the begin curly with prologue_end=false. The codegen will | 2328 | // Emit a line for the begin curly with prologue_end=false. The codegen will |
| 2329 | // do the work of setting prologue_end=true and epilogue_begin=true. | 2329 | // do the work of setting prologue_end=true and epilogue_begin=true. |
| 2330 | dbg_line_buffer.appendAssumeCapacity(DW.LNS_copy); | 2330 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy); |
| 2331 | 2331 | ||
| 2332 | // .debug_info subprogram | 2332 | // .debug_info subprogram |
| 2333 | const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1]; | 2333 | const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1]; |
| ... | @@ -2344,9 +2344,9 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven | ... | @@ -2344,9 +2344,9 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven |
| 2344 | // "relocations" and have to be in this fixed place so that functions can be | 2344 | // "relocations" and have to be in this fixed place so that functions can be |
| 2345 | // moved in virtual address space. | 2345 | // moved in virtual address space. |
| 2346 | assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len); | 2346 | assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len); |
| 2347 | dbg_info_buffer.items.len += ptr_width_bytes; // DW.AT_low_pc, DW.FORM_addr | 2347 | dbg_info_buffer.items.len += ptr_width_bytes; // DW.AT.low_pc, DW.FORM.addr |
| 2348 | assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len); | 2348 | assert(self.getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len); |
| 2349 | dbg_info_buffer.items.len += 4; // DW.AT_high_pc, DW.FORM_data4 | 2349 | dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4 |
| 2350 | if (fn_ret_has_bits) { | 2350 | if (fn_ret_has_bits) { |
| 2351 | const gop = try dbg_info_type_relocs.getOrPut(self.base.allocator, fn_ret_type); | 2351 | const gop = try dbg_info_type_relocs.getOrPut(self.base.allocator, fn_ret_type); |
| 2352 | if (!gop.found_existing) { | 2352 | if (!gop.found_existing) { |
| ... | @@ -2356,9 +2356,9 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven | ... | @@ -2356,9 +2356,9 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven |
| 2356 | }; | 2356 | }; |
| 2357 | } | 2357 | } |
| 2358 | try gop.value_ptr.relocs.append(self.base.allocator, @intCast(u32, dbg_info_buffer.items.len)); | 2358 | try gop.value_ptr.relocs.append(self.base.allocator, @intCast(u32, dbg_info_buffer.items.len)); |
| 2359 | dbg_info_buffer.items.len += 4; // DW.AT_type, DW.FORM_ref4 | 2359 | dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4 |
| 2360 | } | 2360 | } |
| 2361 | dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT_name, DW.FORM_string | 2361 | dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT.name, DW.FORM.string |
| 2362 | 2362 | ||
| 2363 | const res = try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{ | 2363 | const res = try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{ |
| 2364 | .dwarf = .{ | 2364 | .dwarf = .{ |
| ... | @@ -2409,7 +2409,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven | ... | @@ -2409,7 +2409,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven |
| 2409 | mem.writeInt(u32, ptr, @intCast(u32, local_sym.st_size), target_endian); | 2409 | mem.writeInt(u32, ptr, @intCast(u32, local_sym.st_size), target_endian); |
| 2410 | } | 2410 | } |
| 2411 | 2411 | ||
| 2412 | try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS_extended_op, 1, DW.LNE_end_sequence }); | 2412 | try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS.extended_op, 1, DW.LNE.end_sequence }); |
| 2413 | 2413 | ||
| 2414 | // Now we have the full contents and may allocate a region to store it. | 2414 | // Now we have the full contents and may allocate a region to store it. |
| 2415 | 2415 | ||
| ... | @@ -2493,7 +2493,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven | ... | @@ -2493,7 +2493,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven |
| 2493 | const file_pos = debug_line_sect.sh_offset + src_fn.off; | 2493 | const file_pos = debug_line_sect.sh_offset + src_fn.off; |
| 2494 | try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos); | 2494 | try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos); |
| 2495 | 2495 | ||
| 2496 | // .debug_info - End the TAG_subprogram children. | 2496 | // .debug_info - End the TAG.subprogram children. |
| 2497 | try dbg_info_buffer.append(0); | 2497 | try dbg_info_buffer.append(0); |
| 2498 | 2498 | ||
| 2499 | return self.finishUpdateDecl(module, decl, &dbg_info_type_relocs, &dbg_info_buffer); | 2499 | return self.finishUpdateDecl(module, decl, &dbg_info_type_relocs, &dbg_info_buffer); |
| ... | @@ -2566,34 +2566,34 @@ fn addDbgInfoType(self: *Elf, ty: Type, dbg_info_buffer: *std.ArrayList(u8)) !vo | ... | @@ -2566,34 +2566,34 @@ fn addDbgInfoType(self: *Elf, ty: Type, dbg_info_buffer: *std.ArrayList(u8)) !vo |
| 2566 | .Bool => { | 2566 | .Bool => { |
| 2567 | try dbg_info_buffer.appendSlice(&[_]u8{ | 2567 | try dbg_info_buffer.appendSlice(&[_]u8{ |
| 2568 | abbrev_base_type, | 2568 | abbrev_base_type, |
| 2569 | DW.ATE_boolean, // DW.AT_encoding , DW.FORM_data1 | 2569 | DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1 |
| 2570 | 1, // DW.AT_byte_size, DW.FORM_data1 | 2570 | 1, // DW.AT.byte_size, DW.FORM.data1 |
| 2571 | 'b', 'o', 'o', 'l', 0, // DW.AT_name, DW.FORM_string | 2571 | 'b', 'o', 'o', 'l', 0, // DW.AT.name, DW.FORM.string |
| 2572 | }); | 2572 | }); |
| 2573 | }, | 2573 | }, |
| 2574 | .Int => { | 2574 | .Int => { |
| 2575 | const info = ty.intInfo(self.base.options.target); | 2575 | const info = ty.intInfo(self.base.options.target); |
| 2576 | try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12); | 2576 | try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12); |
| 2577 | dbg_info_buffer.appendAssumeCapacity(abbrev_base_type); | 2577 | dbg_info_buffer.appendAssumeCapacity(abbrev_base_type); |
| 2578 | // DW.AT_encoding, DW.FORM_data1 | 2578 | // DW.AT.encoding, DW.FORM.data1 |
| 2579 | dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) { | 2579 | dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) { |
| 2580 | .signed => DW.ATE_signed, | 2580 | .signed => DW.ATE.signed, |
| 2581 | .unsigned => DW.ATE_unsigned, | 2581 | .unsigned => DW.ATE.unsigned, |
| 2582 | }); | 2582 | }); |
| 2583 | // DW.AT_byte_size, DW.FORM_data1 | 2583 | // DW.AT.byte_size, DW.FORM.data1 |
| 2584 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target))); | 2584 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target))); |
| 2585 | // DW.AT_name, DW.FORM_string | 2585 | // DW.AT.name, DW.FORM.string |
| 2586 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); | 2586 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); |
| 2587 | }, | 2587 | }, |
| 2588 | .Optional => { | 2588 | .Optional => { |
| 2589 | if (ty.isPtrLikeOptional()) { | 2589 | if (ty.isPtrLikeOptional()) { |
| 2590 | try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12); | 2590 | try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12); |
| 2591 | dbg_info_buffer.appendAssumeCapacity(abbrev_base_type); | 2591 | dbg_info_buffer.appendAssumeCapacity(abbrev_base_type); |
| 2592 | // DW.AT_encoding, DW.FORM_data1 | 2592 | // DW.AT.encoding, DW.FORM.data1 |
| 2593 | dbg_info_buffer.appendAssumeCapacity(DW.ATE_address); | 2593 | dbg_info_buffer.appendAssumeCapacity(DW.ATE.address); |
| 2594 | // DW.AT_byte_size, DW.FORM_data1 | 2594 | // DW.AT.byte_size, DW.FORM.data1 |
| 2595 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target))); | 2595 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(self.base.options.target))); |
| 2596 | // DW.AT_name, DW.FORM_string | 2596 | // DW.AT.name, DW.FORM.string |
| 2597 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); | 2597 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); |
| 2598 | } else { | 2598 | } else { |
| 2599 | log.err("TODO implement .debug_info for type '{}'", .{ty}); | 2599 | log.err("TODO implement .debug_info for type '{}'", .{ty}); |
| ... | @@ -3034,7 +3034,7 @@ fn archPtrWidthBytes(self: Elf) u8 { | ... | @@ -3034,7 +3034,7 @@ fn archPtrWidthBytes(self: Elf) u8 { |
| 3034 | /// The reloc offset for the virtual address of a function in its Line Number Program. | 3034 | /// The reloc offset for the virtual address of a function in its Line Number Program. |
| 3035 | /// Size is a virtual address integer. | 3035 | /// Size is a virtual address integer. |
| 3036 | const dbg_line_vaddr_reloc_index = 3; | 3036 | const dbg_line_vaddr_reloc_index = 3; |
| 3037 | /// The reloc offset for the virtual address of a function in its .debug_info TAG_subprogram. | 3037 | /// The reloc offset for the virtual address of a function in its .debug_info TAG.subprogram. |
| 3038 | /// Size is a virtual address integer. | 3038 | /// Size is a virtual address integer. |
| 3039 | const dbg_info_low_pc_reloc_index = 1; | 3039 | const dbg_info_low_pc_reloc_index = 1; |
| 3040 | 3040 | ||
| ... | @@ -3060,7 +3060,7 @@ fn dbgLineNeededHeaderBytes(self: Elf) u32 { | ... | @@ -3060,7 +3060,7 @@ fn dbgLineNeededHeaderBytes(self: Elf) u32 { |
| 3060 | const root_src_dir_path_len = if (self.base.options.module.?.root_pkg.root_src_directory.path) |p| p.len else 1; // "." | 3060 | const root_src_dir_path_len = if (self.base.options.module.?.root_pkg.root_src_directory.path) |p| p.len else 1; // "." |
| 3061 | return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 + | 3061 | return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 + |
| 3062 | directory_count * 8 + file_name_count * 8 + | 3062 | directory_count * 8 + file_name_count * 8 + |
| 3063 | // These are encoded as DW.FORM_string rather than DW.FORM_strp as we would like | 3063 | // These are encoded as DW.FORM.string rather than DW.FORM.strp as we would like |
| 3064 | // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly. | 3064 | // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly. |
| 3065 | root_src_dir_path_len + | 3065 | root_src_dir_path_len + |
| 3066 | self.base.options.module.?.root_pkg.root_src_path.len); | 3066 | self.base.options.module.?.root_pkg.root_src_path.len); |
| ... | @@ -3088,8 +3088,8 @@ fn pwriteDbgLineNops( | ... | @@ -3088,8 +3088,8 @@ fn pwriteDbgLineNops( |
| 3088 | const tracy = trace(@src()); | 3088 | const tracy = trace(@src()); |
| 3089 | defer tracy.end(); | 3089 | defer tracy.end(); |
| 3090 | 3090 | ||
| 3091 | const page_of_nops = [1]u8{DW.LNS_negate_stmt} ** 4096; | 3091 | const page_of_nops = [1]u8{DW.LNS.negate_stmt} ** 4096; |
| 3092 | const three_byte_nop = [3]u8{ DW.LNS_advance_pc, 0b1000_0000, 0 }; | 3092 | const three_byte_nop = [3]u8{ DW.LNS.advance_pc, 0b1000_0000, 0 }; |
| 3093 | var vecs: [512]std.os.iovec_const = undefined; | 3093 | var vecs: [512]std.os.iovec_const = undefined; |
| 3094 | var vec_index: usize = 0; | 3094 | var vec_index: usize = 0; |
| 3095 | { | 3095 | { |
src/link/MachO/DebugSymbols.zig+70-70| ... | @@ -93,7 +93,7 @@ const abbrev_parameter = 6; | ... | @@ -93,7 +93,7 @@ const abbrev_parameter = 6; |
| 93 | /// The reloc offset for the virtual address of a function in its Line Number Program. | 93 | /// The reloc offset for the virtual address of a function in its Line Number Program. |
| 94 | /// Size is a virtual address integer. | 94 | /// Size is a virtual address integer. |
| 95 | const dbg_line_vaddr_reloc_index = 3; | 95 | const dbg_line_vaddr_reloc_index = 3; |
| 96 | /// The reloc offset for the virtual address of a function in its .debug_info TAG_subprogram. | 96 | /// The reloc offset for the virtual address of a function in its .debug_info TAG.subprogram. |
| 97 | /// Size is a virtual address integer. | 97 | /// Size is a virtual address integer. |
| 98 | const dbg_info_low_pc_reloc_index = 1; | 98 | const dbg_info_low_pc_reloc_index = 1; |
| 99 | 99 | ||
| ... | @@ -299,40 +299,40 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt | ... | @@ -299,40 +299,40 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt |
| 299 | // These are LEB encoded but since the values are all less than 127 | 299 | // These are LEB encoded but since the values are all less than 127 |
| 300 | // we can simply append these bytes. | 300 | // we can simply append these bytes. |
| 301 | const abbrev_buf = [_]u8{ | 301 | const abbrev_buf = [_]u8{ |
| 302 | abbrev_compile_unit, DW.TAG_compile_unit, DW.CHILDREN_yes, // header | 302 | abbrev_compile_unit, DW.TAG.compile_unit, DW.CHILDREN.yes, // header |
| 303 | DW.AT_stmt_list, DW.FORM_sec_offset, // offset | 303 | DW.AT.stmt_list, DW.FORM.sec_offset, // offset |
| 304 | DW.AT_low_pc, DW.FORM_addr, | 304 | DW.AT.low_pc, DW.FORM.addr, |
| 305 | DW.AT_high_pc, DW.FORM_addr, | 305 | DW.AT.high_pc, DW.FORM.addr, |
| 306 | DW.AT_name, DW.FORM_strp, | 306 | DW.AT.name, DW.FORM.strp, |
| 307 | DW.AT_comp_dir, DW.FORM_strp, | 307 | DW.AT.comp_dir, DW.FORM.strp, |
| 308 | DW.AT_producer, DW.FORM_strp, | 308 | DW.AT.producer, DW.FORM.strp, |
| 309 | DW.AT_language, DW.FORM_data2, | 309 | DW.AT.language, DW.FORM.data2, |
| 310 | 0, 0, // table sentinel | 310 | 0, 0, // table sentinel |
| 311 | abbrev_subprogram, DW.TAG_subprogram, DW.CHILDREN_yes, // header | 311 | abbrev_subprogram, DW.TAG.subprogram, DW.CHILDREN.yes, // header |
| 312 | DW.AT_low_pc, DW.FORM_addr, // start VM address | 312 | DW.AT.low_pc, DW.FORM.addr, // start VM address |
| 313 | DW.AT_high_pc, DW.FORM_data4, | 313 | DW.AT.high_pc, DW.FORM.data4, |
| 314 | DW.AT_type, DW.FORM_ref4, | 314 | DW.AT.type, DW.FORM.ref4, |
| 315 | DW.AT_name, DW.FORM_string, | 315 | DW.AT.name, DW.FORM.string, |
| 316 | DW.AT_decl_line, DW.FORM_data4, | 316 | DW.AT.decl_line, DW.FORM.data4, |
| 317 | DW.AT_decl_file, DW.FORM_data1, | 317 | DW.AT.decl_file, DW.FORM.data1, |
| 318 | 0, 0, // table sentinel | 318 | 0, 0, // table sentinel |
| 319 | abbrev_subprogram_retvoid, | 319 | abbrev_subprogram_retvoid, |
| 320 | DW.TAG_subprogram, DW.CHILDREN_yes, // header | 320 | DW.TAG.subprogram, DW.CHILDREN.yes, // header |
| 321 | DW.AT_low_pc, DW.FORM_addr, | 321 | DW.AT.low_pc, DW.FORM.addr, |
| 322 | DW.AT_high_pc, DW.FORM_data4, | 322 | DW.AT.high_pc, DW.FORM.data4, |
| 323 | DW.AT_name, DW.FORM_string, | 323 | DW.AT.name, DW.FORM.string, |
| 324 | DW.AT_decl_line, DW.FORM_data4, | 324 | DW.AT.decl_line, DW.FORM.data4, |
| 325 | DW.AT_decl_file, DW.FORM_data1, | 325 | DW.AT.decl_file, DW.FORM.data1, |
| 326 | 0, 0, // table sentinel | 326 | 0, 0, // table sentinel |
| 327 | abbrev_base_type, DW.TAG_base_type, DW.CHILDREN_no, // header | 327 | abbrev_base_type, DW.TAG.base_type, DW.CHILDREN.no, // header |
| 328 | DW.AT_encoding, DW.FORM_data1, DW.AT_byte_size, | 328 | DW.AT.encoding, DW.FORM.data1, DW.AT.byte_size, |
| 329 | DW.FORM_data1, DW.AT_name, DW.FORM_string, | 329 | DW.FORM.data1, DW.AT.name, DW.FORM.string, |
| 330 | 0, 0, // table sentinel | 330 | 0, 0, // table sentinel |
| 331 | abbrev_pad1, DW.TAG_unspecified_type, DW.CHILDREN_no, // header | 331 | abbrev_pad1, DW.TAG.unspecified_type, DW.CHILDREN.no, // header |
| 332 | 0, 0, // table sentinel | 332 | 0, 0, // table sentinel |
| 333 | abbrev_parameter, DW.TAG_formal_parameter, DW.CHILDREN_no, // header | 333 | abbrev_parameter, DW.TAG.formal_parameter, DW.CHILDREN.no, // header |
| 334 | DW.AT_location, DW.FORM_exprloc, DW.AT_type, | 334 | DW.AT.location, DW.FORM.exprloc, DW.AT.type, |
| 335 | DW.FORM_ref4, DW.AT_name, DW.FORM_string, | 335 | DW.FORM.ref4, DW.AT.name, DW.FORM.string, |
| 336 | 0, 0, // table sentinel | 336 | 0, 0, // table sentinel |
| 337 | 0, 0, 0, // section sentinel | 337 | 0, 0, 0, // section sentinel |
| 338 | }; | 338 | }; |
| ... | @@ -397,7 +397,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt | ... | @@ -397,7 +397,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt |
| 397 | const high_pc = text_section.addr + text_section.size; | 397 | const high_pc = text_section.addr + text_section.size; |
| 398 | 398 | ||
| 399 | di_buf.appendAssumeCapacity(abbrev_compile_unit); | 399 | di_buf.appendAssumeCapacity(abbrev_compile_unit); |
| 400 | mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // DW.AT_stmt_list, DW.FORM_sec_offset | 400 | mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), 0); // DW.AT.stmt_list, DW.FORM.sec_offset |
| 401 | mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), low_pc); | 401 | mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), low_pc); |
| 402 | mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), high_pc); | 402 | mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), high_pc); |
| 403 | mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, name_strp)); | 403 | mem.writeIntLittle(u32, di_buf.addManyAsArrayAssumeCapacity(4), @intCast(u32, name_strp)); |
| ... | @@ -406,7 +406,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt | ... | @@ -406,7 +406,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt |
| 406 | // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number: | 406 | // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number: |
| 407 | // http://dwarfstd.org/ShowIssue.php?issue=171115.1 | 407 | // http://dwarfstd.org/ShowIssue.php?issue=171115.1 |
| 408 | // Until then we say it is C99. | 408 | // Until then we say it is C99. |
| 409 | mem.writeIntLittle(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG_C99); | 409 | mem.writeIntLittle(u16, di_buf.addManyAsArrayAssumeCapacity(2), DW.LANG.C99); |
| 410 | 410 | ||
| 411 | if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) { | 411 | if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) { |
| 412 | // Move the first N decls to the end to make more padding for the header. | 412 | // Move the first N decls to the end to make more padding for the header. |
| ... | @@ -514,7 +514,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt | ... | @@ -514,7 +514,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt |
| 514 | di_buf.items.len += @sizeOf(u32); // We will come back and write this. | 514 | di_buf.items.len += @sizeOf(u32); // We will come back and write this. |
| 515 | const after_header_len = di_buf.items.len; | 515 | const after_header_len = di_buf.items.len; |
| 516 | 516 | ||
| 517 | const opcode_base = DW.LNS_set_isa + 1; | 517 | const opcode_base = DW.LNS.set_isa + 1; |
| 518 | di_buf.appendSliceAssumeCapacity(&[_]u8{ | 518 | di_buf.appendSliceAssumeCapacity(&[_]u8{ |
| 519 | 1, // minimum_instruction_length | 519 | 1, // minimum_instruction_length |
| 520 | 1, // maximum_operations_per_instruction | 520 | 1, // maximum_operations_per_instruction |
| ... | @@ -525,18 +525,18 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt | ... | @@ -525,18 +525,18 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt |
| 525 | 525 | ||
| 526 | // Standard opcode lengths. The number of items here is based on `opcode_base`. | 526 | // Standard opcode lengths. The number of items here is based on `opcode_base`. |
| 527 | // The value is the number of LEB128 operands the instruction takes. | 527 | // The value is the number of LEB128 operands the instruction takes. |
| 528 | 0, // `DW.LNS_copy` | 528 | 0, // `DW.LNS.copy` |
| 529 | 1, // `DW.LNS_advance_pc` | 529 | 1, // `DW.LNS.advance_pc` |
| 530 | 1, // `DW.LNS_advance_line` | 530 | 1, // `DW.LNS.advance_line` |
| 531 | 1, // `DW.LNS_set_file` | 531 | 1, // `DW.LNS.set_file` |
| 532 | 1, // `DW.LNS_set_column` | 532 | 1, // `DW.LNS.set_column` |
| 533 | 0, // `DW.LNS_negate_stmt` | 533 | 0, // `DW.LNS.negate_stmt` |
| 534 | 0, // `DW.LNS_set_basic_block` | 534 | 0, // `DW.LNS.set_basic_block` |
| 535 | 0, // `DW.LNS_const_add_pc` | 535 | 0, // `DW.LNS.const_add_pc` |
| 536 | 1, // `DW.LNS_fixed_advance_pc` | 536 | 1, // `DW.LNS.fixed_advance_pc` |
| 537 | 0, // `DW.LNS_set_prologue_end` | 537 | 0, // `DW.LNS.set_prologue_end` |
| 538 | 0, // `DW.LNS_set_epilogue_begin` | 538 | 0, // `DW.LNS.set_epilogue_begin` |
| 539 | 1, // `DW.LNS_set_isa` | 539 | 1, // `DW.LNS.set_isa` |
| 540 | 0, // include_directories (none except the compilation unit cwd) | 540 | 0, // include_directories (none except the compilation unit cwd) |
| 541 | }); | 541 | }); |
| 542 | // file_names[0] | 542 | // file_names[0] |
| ... | @@ -876,22 +876,22 @@ pub fn initDeclDebugBuffers( | ... | @@ -876,22 +876,22 @@ pub fn initDeclDebugBuffers( |
| 876 | const line_off = @intCast(u28, decl.src_line + func.lbrace_line); | 876 | const line_off = @intCast(u28, decl.src_line + func.lbrace_line); |
| 877 | 877 | ||
| 878 | dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{ | 878 | dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{ |
| 879 | DW.LNS_extended_op, | 879 | DW.LNS.extended_op, |
| 880 | @sizeOf(u64) + 1, | 880 | @sizeOf(u64) + 1, |
| 881 | DW.LNE_set_address, | 881 | DW.LNE.set_address, |
| 882 | }); | 882 | }); |
| 883 | // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`. | 883 | // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`. |
| 884 | assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len); | 884 | assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len); |
| 885 | dbg_line_buffer.items.len += @sizeOf(u64); | 885 | dbg_line_buffer.items.len += @sizeOf(u64); |
| 886 | 886 | ||
| 887 | dbg_line_buffer.appendAssumeCapacity(DW.LNS_advance_line); | 887 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.advance_line); |
| 888 | // This is the "relocatable" relative line offset from the previous function's end curly | 888 | // This is the "relocatable" relative line offset from the previous function's end curly |
| 889 | // to this function's begin curly. | 889 | // to this function's begin curly. |
| 890 | assert(getRelocDbgLineOff() == dbg_line_buffer.items.len); | 890 | assert(getRelocDbgLineOff() == dbg_line_buffer.items.len); |
| 891 | // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later. | 891 | // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later. |
| 892 | leb.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off); | 892 | leb.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off); |
| 893 | 893 | ||
| 894 | dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file); | 894 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_file); |
| 895 | assert(getRelocDbgFileIndex() == dbg_line_buffer.items.len); | 895 | assert(getRelocDbgFileIndex() == dbg_line_buffer.items.len); |
| 896 | // Once we support more than one source file, this will have the ability to be more | 896 | // Once we support more than one source file, this will have the ability to be more |
| 897 | // than one possible value. | 897 | // than one possible value. |
| ... | @@ -900,7 +900,7 @@ pub fn initDeclDebugBuffers( | ... | @@ -900,7 +900,7 @@ pub fn initDeclDebugBuffers( |
| 900 | 900 | ||
| 901 | // Emit a line for the begin curly with prologue_end=false. The codegen will | 901 | // Emit a line for the begin curly with prologue_end=false. The codegen will |
| 902 | // do the work of setting prologue_end=true and epilogue_begin=true. | 902 | // do the work of setting prologue_end=true and epilogue_begin=true. |
| 903 | dbg_line_buffer.appendAssumeCapacity(DW.LNS_copy); | 903 | dbg_line_buffer.appendAssumeCapacity(DW.LNS.copy); |
| 904 | 904 | ||
| 905 | // .debug_info subprogram | 905 | // .debug_info subprogram |
| 906 | const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1]; | 906 | const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1]; |
| ... | @@ -917,9 +917,9 @@ pub fn initDeclDebugBuffers( | ... | @@ -917,9 +917,9 @@ pub fn initDeclDebugBuffers( |
| 917 | // "relocations" and have to be in this fixed place so that functions can be | 917 | // "relocations" and have to be in this fixed place so that functions can be |
| 918 | // moved in virtual address space. | 918 | // moved in virtual address space. |
| 919 | assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len); | 919 | assert(dbg_info_low_pc_reloc_index == dbg_info_buffer.items.len); |
| 920 | dbg_info_buffer.items.len += @sizeOf(u64); // DW.AT_low_pc, DW.FORM_addr | 920 | dbg_info_buffer.items.len += @sizeOf(u64); // DW.AT.low_pc, DW.FORM.addr |
| 921 | assert(getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len); | 921 | assert(getRelocDbgInfoSubprogramHighPC() == dbg_info_buffer.items.len); |
| 922 | dbg_info_buffer.items.len += 4; // DW.AT_high_pc, DW.FORM_data4 | 922 | dbg_info_buffer.items.len += 4; // DW.AT.high_pc, DW.FORM.data4 |
| 923 | if (fn_ret_has_bits) { | 923 | if (fn_ret_has_bits) { |
| 924 | const gop = try dbg_info_type_relocs.getOrPut(allocator, fn_ret_type); | 924 | const gop = try dbg_info_type_relocs.getOrPut(allocator, fn_ret_type); |
| 925 | if (!gop.found_existing) { | 925 | if (!gop.found_existing) { |
| ... | @@ -929,11 +929,11 @@ pub fn initDeclDebugBuffers( | ... | @@ -929,11 +929,11 @@ pub fn initDeclDebugBuffers( |
| 929 | }; | 929 | }; |
| 930 | } | 930 | } |
| 931 | try gop.value_ptr.relocs.append(allocator, @intCast(u32, dbg_info_buffer.items.len)); | 931 | try gop.value_ptr.relocs.append(allocator, @intCast(u32, dbg_info_buffer.items.len)); |
| 932 | dbg_info_buffer.items.len += 4; // DW.AT_type, DW.FORM_ref4 | 932 | dbg_info_buffer.items.len += 4; // DW.AT.type, DW.FORM.ref4 |
| 933 | } | 933 | } |
| 934 | dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT_name, DW.FORM_string | 934 | dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT.name, DW.FORM.string |
| 935 | mem.writeIntLittle(u32, dbg_info_buffer.addManyAsArrayAssumeCapacity(4), line_off + 1); // DW.AT_decl_line, DW.FORM_data4 | 935 | mem.writeIntLittle(u32, dbg_info_buffer.addManyAsArrayAssumeCapacity(4), line_off + 1); // DW.AT.decl_line, DW.FORM.data4 |
| 936 | dbg_info_buffer.appendAssumeCapacity(file_index); // DW.AT_decl_file, DW.FORM_data1 | 936 | dbg_info_buffer.appendAssumeCapacity(file_index); // DW.AT.decl_file, DW.FORM.data1 |
| 937 | }, | 937 | }, |
| 938 | else => { | 938 | else => { |
| 939 | // TODO implement .debug_info for global variables | 939 | // TODO implement .debug_info for global variables |
| ... | @@ -985,16 +985,16 @@ pub fn commitDeclDebugInfo( | ... | @@ -985,16 +985,16 @@ pub fn commitDeclDebugInfo( |
| 985 | { | 985 | { |
| 986 | // Advance line and PC. | 986 | // Advance line and PC. |
| 987 | // TODO encapsulate logic in a helper function. | 987 | // TODO encapsulate logic in a helper function. |
| 988 | try dbg_line_buffer.append(DW.LNS_advance_pc); | 988 | try dbg_line_buffer.append(DW.LNS.advance_pc); |
| 989 | try leb.writeULEB128(dbg_line_buffer.writer(), text_block.size); | 989 | try leb.writeULEB128(dbg_line_buffer.writer(), text_block.size); |
| 990 | 990 | ||
| 991 | try dbg_line_buffer.append(DW.LNS_advance_line); | 991 | try dbg_line_buffer.append(DW.LNS.advance_line); |
| 992 | const func = decl.val.castTag(.function).?.data; | 992 | const func = decl.val.castTag(.function).?.data; |
| 993 | const line_off = @intCast(u28, func.rbrace_line - func.lbrace_line); | 993 | const line_off = @intCast(u28, func.rbrace_line - func.lbrace_line); |
| 994 | try leb.writeULEB128(dbg_line_buffer.writer(), line_off); | 994 | try leb.writeULEB128(dbg_line_buffer.writer(), line_off); |
| 995 | } | 995 | } |
| 996 | 996 | ||
| 997 | try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS_extended_op, 1, DW.LNE_end_sequence }); | 997 | try dbg_line_buffer.appendSlice(&[_]u8{ DW.LNS.extended_op, 1, DW.LNE.end_sequence }); |
| 998 | 998 | ||
| 999 | // Now we have the full contents and may allocate a region to store it. | 999 | // Now we have the full contents and may allocate a region to store it. |
| 1000 | 1000 | ||
| ... | @@ -1075,7 +1075,7 @@ pub fn commitDeclDebugInfo( | ... | @@ -1075,7 +1075,7 @@ pub fn commitDeclDebugInfo( |
| 1075 | const file_pos = debug_line_sect.offset + src_fn.off; | 1075 | const file_pos = debug_line_sect.offset + src_fn.off; |
| 1076 | try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos); | 1076 | try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos); |
| 1077 | 1077 | ||
| 1078 | // .debug_info - End the TAG_subprogram children. | 1078 | // .debug_info - End the TAG.subprogram children. |
| 1079 | try dbg_info_buffer.append(0); | 1079 | try dbg_info_buffer.append(0); |
| 1080 | }, | 1080 | }, |
| 1081 | else => {}, | 1081 | else => {}, |
| ... | @@ -1128,27 +1128,27 @@ fn addDbgInfoType( | ... | @@ -1128,27 +1128,27 @@ fn addDbgInfoType( |
| 1128 | .Bool => { | 1128 | .Bool => { |
| 1129 | try dbg_info_buffer.appendSlice(&[_]u8{ | 1129 | try dbg_info_buffer.appendSlice(&[_]u8{ |
| 1130 | abbrev_base_type, | 1130 | abbrev_base_type, |
| 1131 | DW.ATE_boolean, // DW.AT_encoding , DW.FORM_data1 | 1131 | DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1 |
| 1132 | 1, // DW.AT_byte_size, DW.FORM_data1 | 1132 | 1, // DW.AT.byte_size, DW.FORM.data1 |
| 1133 | 'b', | 1133 | 'b', |
| 1134 | 'o', | 1134 | 'o', |
| 1135 | 'o', | 1135 | 'o', |
| 1136 | 'l', | 1136 | 'l', |
| 1137 | 0, // DW.AT_name, DW.FORM_string | 1137 | 0, // DW.AT.name, DW.FORM.string |
| 1138 | }); | 1138 | }); |
| 1139 | }, | 1139 | }, |
| 1140 | .Int => { | 1140 | .Int => { |
| 1141 | const info = ty.intInfo(target); | 1141 | const info = ty.intInfo(target); |
| 1142 | try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12); | 1142 | try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12); |
| 1143 | dbg_info_buffer.appendAssumeCapacity(abbrev_base_type); | 1143 | dbg_info_buffer.appendAssumeCapacity(abbrev_base_type); |
| 1144 | // DW.AT_encoding, DW.FORM_data1 | 1144 | // DW.AT.encoding, DW.FORM.data1 |
| 1145 | dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) { | 1145 | dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) { |
| 1146 | .signed => DW.ATE_signed, | 1146 | .signed => DW.ATE.signed, |
| 1147 | .unsigned => DW.ATE_unsigned, | 1147 | .unsigned => DW.ATE.unsigned, |
| 1148 | }); | 1148 | }); |
| 1149 | // DW.AT_byte_size, DW.FORM_data1 | 1149 | // DW.AT.byte_size, DW.FORM.data1 |
| 1150 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target))); | 1150 | dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target))); |
| 1151 | // DW.AT_name, DW.FORM_string | 1151 | // DW.AT.name, DW.FORM.string |
| 1152 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); | 1152 | try dbg_info_buffer.writer().print("{}\x00", .{ty}); |
| 1153 | }, | 1153 | }, |
| 1154 | else => { | 1154 | else => { |
| ... | @@ -1306,7 +1306,7 @@ fn dbgLineNeededHeaderBytes(self: DebugSymbols, module: *Module) u32 { | ... | @@ -1306,7 +1306,7 @@ fn dbgLineNeededHeaderBytes(self: DebugSymbols, module: *Module) u32 { |
| 1306 | const root_src_dir_path_len = if (module.root_pkg.root_src_directory.path) |p| p.len else 1; // "." | 1306 | const root_src_dir_path_len = if (module.root_pkg.root_src_directory.path) |p| p.len else 1; // "." |
| 1307 | return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 + | 1307 | return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 + |
| 1308 | directory_count * 8 + file_name_count * 8 + | 1308 | directory_count * 8 + file_name_count * 8 + |
| 1309 | // These are encoded as DW.FORM_string rather than DW.FORM_strp as we would like | 1309 | // These are encoded as DW.FORM.string rather than DW.FORM.strp as we would like |
| 1310 | // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly. | 1310 | // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly. |
| 1311 | root_src_dir_path_len + | 1311 | root_src_dir_path_len + |
| 1312 | module.root_pkg.root_src_path.len); | 1312 | module.root_pkg.root_src_path.len); |
| ... | @@ -1332,8 +1332,8 @@ fn pwriteDbgLineNops( | ... | @@ -1332,8 +1332,8 @@ fn pwriteDbgLineNops( |
| 1332 | const tracy = trace(@src()); | 1332 | const tracy = trace(@src()); |
| 1333 | defer tracy.end(); | 1333 | defer tracy.end(); |
| 1334 | 1334 | ||
| 1335 | const page_of_nops = [1]u8{DW.LNS_negate_stmt} ** 4096; | 1335 | const page_of_nops = [1]u8{DW.LNS.negate_stmt} ** 4096; |
| 1336 | const three_byte_nop = [3]u8{ DW.LNS_advance_pc, 0b1000_0000, 0 }; | 1336 | const three_byte_nop = [3]u8{ DW.LNS.advance_pc, 0b1000_0000, 0 }; |
| 1337 | var vecs: [32]std.os.iovec_const = undefined; | 1337 | var vecs: [32]std.os.iovec_const = undefined; |
| 1338 | var vec_index: usize = 0; | 1338 | var vec_index: usize = 0; |
| 1339 | { | 1339 | { |
src/link/MachO/Object.zig+2-2| ... | @@ -836,8 +836,8 @@ pub fn parseDebugInfo(self: *Object, allocator: *Allocator) !void { | ... | @@ -836,8 +836,8 @@ pub fn parseDebugInfo(self: *Object, allocator: *Allocator) !void { |
| 836 | }, | 836 | }, |
| 837 | else => |e| return e, | 837 | else => |e| return e, |
| 838 | }; | 838 | }; |
| 839 | const name = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT_name); | 839 | const name = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT.name); |
| 840 | const comp_dir = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT_comp_dir); | 840 | const comp_dir = try compile_unit.die.getAttrString(&debug_info.inner, dwarf.AT.comp_dir); |
| 841 | 841 | ||
| 842 | self.debug_info = debug_info; | 842 | self.debug_info = debug_info; |
| 843 | self.tu_name = try allocator.dupe(u8, name); | 843 | self.tu_name = try allocator.dupe(u8, name); |
test/behavior.zig+2-1| ... | @@ -10,6 +10,7 @@ test { | ... | @@ -10,6 +10,7 @@ test { |
| 10 | _ = @import("behavior/if.zig"); | 10 | _ = @import("behavior/if.zig"); |
| 11 | _ = @import("behavior/cast.zig"); | 11 | _ = @import("behavior/cast.zig"); |
| 12 | _ = @import("behavior/array.zig"); | 12 | _ = @import("behavior/array.zig"); |
| 13 | _ = @import("behavior/usingnamespace.zig"); | ||
| 13 | 14 | ||
| 14 | if (!builtin.zig_is_stage2) { | 15 | if (!builtin.zig_is_stage2) { |
| 15 | // Tests that only pass for stage1. | 16 | // Tests that only pass for stage1. |
| ... | @@ -148,7 +149,7 @@ test { | ... | @@ -148,7 +149,7 @@ test { |
| 148 | _ = @import("behavior/undefined.zig"); | 149 | _ = @import("behavior/undefined.zig"); |
| 149 | _ = @import("behavior/underscore.zig"); | 150 | _ = @import("behavior/underscore.zig"); |
| 150 | _ = @import("behavior/union.zig"); | 151 | _ = @import("behavior/union.zig"); |
| 151 | _ = @import("behavior/usingnamespace.zig"); | 152 | _ = @import("behavior/usingnamespace_stage1.zig"); |
| 152 | _ = @import("behavior/var_args.zig"); | 153 | _ = @import("behavior/var_args.zig"); |
| 153 | _ = @import("behavior/vector.zig"); | 154 | _ = @import("behavior/vector.zig"); |
| 154 | _ = @import("behavior/void.zig"); | 155 | _ = @import("behavior/void.zig"); |
test/behavior/eval.zig-6| ... | @@ -125,12 +125,6 @@ test "pointer to type" { | ... | @@ -125,12 +125,6 @@ test "pointer to type" { |
| 125 | } | 125 | } |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | test "no undeclared identifier error in unanalyzed branches" { | ||
| 129 | if (false) { | ||
| 130 | lol_this_doesnt_exist = nonsense; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | test "a type constructed in a global expression" { | 128 | test "a type constructed in a global expression" { |
| 135 | var l: List = undefined; | 129 | var l: List = undefined; |
| 136 | l.array[0] = 10; | 130 | l.array[0] = 10; |
test/behavior/usingnamespace.zig+7-16| ... | @@ -1,22 +1,13 @@ | ... | @@ -1,22 +1,13 @@ |
| 1 | const std = @import("std"); | 1 | const std = @import("std"); |
| 2 | 2 | ||
| 3 | fn Foo(comptime T: type) type { | 3 | const A = struct { |
| 4 | return struct { | 4 | pub const B = bool; |
| 5 | usingnamespace T; | 5 | }; |
| 6 | }; | ||
| 7 | } | ||
| 8 | |||
| 9 | test "usingnamespace inside a generic struct" { | ||
| 10 | const std2 = Foo(std); | ||
| 11 | const testing2 = Foo(std.testing); | ||
| 12 | try std2.testing.expect(true); | ||
| 13 | try testing2.expect(true); | ||
| 14 | } | ||
| 15 | 6 | ||
| 16 | usingnamespace struct { | 7 | const C = struct { |
| 17 | pub const foo = 42; | 8 | usingnamespace A; |
| 18 | }; | 9 | }; |
| 19 | 10 | ||
| 20 | test "usingnamespace does not redeclare an imported variable" { | 11 | test "basic usingnamespace" { |
| 21 | comptime try std.testing.expect(foo == 42); | 12 | try std.testing.expect(C.B == bool); |
| 22 | } | 13 | } |
test/behavior/usingnamespace_stage1.zig created+22| ... | @@ -0,0 +1,22 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | fn Foo(comptime T: type) type { | ||
| 4 | return struct { | ||
| 5 | usingnamespace T; | ||
| 6 | }; | ||
| 7 | } | ||
| 8 | |||
| 9 | test "usingnamespace inside a generic struct" { | ||
| 10 | const std2 = Foo(std); | ||
| 11 | const testing2 = Foo(std.testing); | ||
| 12 | try std2.testing.expect(true); | ||
| 13 | try testing2.expect(true); | ||
| 14 | } | ||
| 15 | |||
| 16 | usingnamespace struct { | ||
| 17 | pub const foo = 42; | ||
| 18 | }; | ||
| 19 | |||
| 20 | test "usingnamespace does not redeclare an imported variable" { | ||
| 21 | comptime try std.testing.expect(foo == 42); | ||
| 22 | } | ||
test/compile_errors.zig+10| ... | @@ -8846,4 +8846,14 @@ pub fn addCases(ctx: *TestContext) !void { | ... | @@ -8846,4 +8846,14 @@ pub fn addCases(ctx: *TestContext) !void { |
| 8846 | , &[_][]const u8{ | 8846 | , &[_][]const u8{ |
| 8847 | "error: invalid operands to binary expression: 'f32' and 'f32'", | 8847 | "error: invalid operands to binary expression: 'f32' and 'f32'", |
| 8848 | }); | 8848 | }); |
| 8849 | |||
| 8850 | ctx.objErrStage1("undeclared identifier in unanalyzed branch", | ||
| 8851 | \\export fn a() void { | ||
| 8852 | \\ if (false) { | ||
| 8853 | \\ lol_this_doesnt_exist = nonsense; | ||
| 8854 | \\ } | ||
| 8855 | \\} | ||
| 8856 | , &[_][]const u8{ | ||
| 8857 | "tmp.zig:3:9: error: use of undeclared identifier 'lol_this_doesnt_exist'", | ||
| 8858 | }); | ||
| 8849 | } | 8859 | } |