authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-28 15:35:59-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-09-01 17:54:06-07:00
log332eafeb7f3d866556ab767b960a04661bc43bc7
treed299cbc233ca756ca42885e66f54e2b08f2a3d9a
parentc05a20fc8c36742dab8792d15e79716da1a55759

stage2: first pass at implementing usingnamespace

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(
64166416 },
64176417 .top => break,
64186418 };
6419 if (found_already == null) {
6420 return astgen.failNode(ident, "use of undeclared identifier '{s}'", .{ident_name});
6421 }
64196422
64206423 // Decl references happen by name rather than ZIR index so that when unrelated
64216424 // decls are modified, ZIR code containing references to them can be unmodified.
......@@ -10052,7 +10055,7 @@ fn isPrimitive(name: []const u8) bool {
1005210055 }
1005310056}
1005410057
10055/// Local variables shadowing detection, including function parameters and primitives.
10058/// Local variables shadowing detection, including function parameters.
1005610059fn detectLocalShadowing(
1005710060 astgen: *AstGen,
1005810061 scope: *Scope,
src/Module.zig+50-12
......@@ -365,6 +365,8 @@ pub const Decl = struct {
365365 /// Decl is marked alive, then it sends the Decl to the linker. Otherwise it
366366 /// deletes the Decl on the spot.
367367 alive: bool,
368 /// Whether the Decl is a `usingnamespace` declaration.
369 is_usingnamespace: bool,
368370
369371 /// Represents the position of the code in the output file.
370372 /// This is populated regardless of semantic analysis and code generation.
......@@ -1008,6 +1010,11 @@ pub const Scope = struct {
10081010
10091011 anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{},
10101012
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
10111018 pub fn deinit(ns: *Namespace, mod: *Module) void {
10121019 ns.destroyDecls(mod);
10131020 ns.* = undefined;
......@@ -3174,6 +3181,31 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
31743181 errdefer decl_arena.deinit();
31753182 const decl_arena_state = try decl_arena.allocator.create(std.heap.ArenaAllocator.State);
31763183
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
31773209 if (decl_tv.val.castTag(.function)) |fn_payload| {
31783210 const func = fn_payload.data;
31793211 const owns_tv = func.owner_decl == decl;
......@@ -3269,16 +3301,13 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
32693301 if (type_changed and mod.emit_h != null) {
32703302 try mod.comp.work_queue.writeItem(.{ .emit_h_decl = decl });
32713303 }
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);
32813304 }
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);
32823311
32833312 if (decl.is_exported) {
32843313 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
34943523
34953524 // zig fmt: off
34963525 const is_pub = (flags & 0b0001) != 0;
3497 const is_exported = (flags & 0b0010) != 0;
3526 const export_bit = (flags & 0b0010) != 0;
34983527 const has_align = (flags & 0b0100) != 0;
34993528 const has_linksection = (flags & 0b1000) != 0;
35003529 // zig fmt: on
......@@ -3509,7 +3538,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
35093538 var is_named_test = false;
35103539 const decl_name: [:0]const u8 = switch (decl_name_index) {
35113540 0 => name: {
3512 if (is_exported) {
3541 if (export_bit) {
35133542 const i = iter.usingnamespace_index;
35143543 iter.usingnamespace_index += 1;
35153544 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
35353564 }
35363565 },
35373566 };
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);
35383570
35393571 // We create a Decl for it regardless of analysis status.
35403572 const gop = try namespace.decls.getOrPut(gpa, decl_name);
35413573 if (!gop.found_existing) {
35423574 const new_decl = try mod.allocateNewDecl(namespace, decl_node);
3575 if (is_usingnamespace) {
3576 namespace.usingnamespace_set.putAssumeCapacity(new_decl, is_pub);
3577 }
35433578 log.debug("scan new {*} ({s}) into {*}", .{ new_decl, decl_name, namespace });
35443579 new_decl.src_line = line;
35453580 new_decl.name = decl_name;
......@@ -3548,7 +3583,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
35483583 // test decls if in test mode, get analyzed.
35493584 const decl_pkg = namespace.file_scope.pkg;
35503585 const want_analysis = is_exported or switch (decl_name_index) {
3551 0 => true, // comptime decl
3586 0 => true, // comptime or usingnamespace decl
35523587 1 => blk: {
35533588 // test decl with no name. Skip the part where we check against
35543589 // the test name filter.
......@@ -3571,6 +3606,7 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) SemaError!voi
35713606 }
35723607 new_decl.is_pub = is_pub;
35733608 new_decl.is_exported = is_exported;
3609 new_decl.is_usingnamespace = is_usingnamespace;
35743610 new_decl.has_align = has_align;
35753611 new_decl.has_linksection = has_linksection;
35763612 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
35873623
35883624 decl.is_pub = is_pub;
35893625 decl.is_exported = is_exported;
3626 decl.is_usingnamespace = is_usingnamespace;
35903627 decl.has_align = has_align;
35913628 decl.has_linksection = has_linksection;
35923629 decl.zir_decl_index = @intCast(u32, decl_sub_index);
......@@ -3979,6 +4016,7 @@ pub fn allocateNewDecl(mod: *Module, namespace: *Scope.Namespace, src_node: ast.
39794016 .has_linksection = false,
39804017 .has_align = false,
39814018 .alive = false,
4019 .is_usingnamespace = false,
39824020 };
39834021 return new_decl;
39844022}
src/Sema.zig+99-16
......@@ -58,6 +58,9 @@ comptime_args_fn_inst: Zir.Inst.Index = 0,
5858/// extra hash table lookup in the `monomorphed_funcs` set.
5959/// Sema will set this to null when it takes ownership.
6060preallocated_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.
63types_pending_resolution: std.ArrayListUnmanaged(Type) = .{},
6164
6265const std = @import("std");
6366const mem = std.mem;
......@@ -90,6 +93,7 @@ pub fn deinit(sema: *Sema) void {
9093 sema.air_values.deinit(gpa);
9194 sema.inst_map.deinit(gpa);
9295 sema.decl_val_table.deinit(gpa);
96 sema.types_pending_resolution.deinit(gpa);
9397 sema.* = undefined;
9498}
9599
......@@ -908,7 +912,9 @@ fn zirStructDecl(
908912 &struct_obj.namespace, new_decl, new_decl.name,
909913 });
910914 try sema.analyzeStructDecl(new_decl, inst, struct_obj);
915 try sema.types_pending_resolution.ensureUnusedCapacity(sema.gpa, 1);
911916 try new_decl.finalizeNewArena(&new_decl_arena);
917 sema.types_pending_resolution.appendAssumeCapacity(struct_ty);
912918 return sema.analyzeDeclVal(block, src, new_decl);
913919}
914920
......@@ -1198,7 +1204,9 @@ fn zirUnionDecl(
11981204
11991205 _ = try sema.mod.scanNamespace(&union_obj.namespace, extra_index, decls_len, new_decl);
12001206
1207 try sema.types_pending_resolution.ensureUnusedCapacity(sema.gpa, 1);
12011208 try new_decl.finalizeNewArena(&new_decl_arena);
1209 sema.types_pending_resolution.appendAssumeCapacity(union_ty);
12021210 return sema.analyzeDeclVal(block, src, new_decl);
12031211}
12041212
......@@ -2324,42 +2332,105 @@ fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErr
23242332}
23252333
23262334fn 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.
23282335 var namespace = sema.namespace;
23292336 while (true) {
2330 if (try sema.lookupInNamespace(namespace, name)) |decl| {
2337 if (try sema.lookupInNamespace(block, src, namespace, name, false)) |decl| {
23312338 return decl;
23322339 }
23332340 namespace = namespace.parent orelse break;
23342341 }
2335 return sema.mod.fail(&block.base, src, "use of undeclared identifier '{s}'", .{name});
2342 unreachable; // AstGen detects use of undeclared identifier errors.
23362343}
23372344
23382345/// This looks up a member of a specific namespace. It is affected by `usingnamespace` but
23392346/// only for ones in the specified namespace.
23402347fn lookupInNamespace(
23412348 sema: *Sema,
2349 block: *Scope.Block,
2350 src: LazySrcLoc,
23422351 namespace: *Scope.Namespace,
23432352 ident_name: []const u8,
2353 observe_usingnamespace: bool,
23442354) CompileError!?*Decl {
2355 const mod = sema.mod;
2356
23452357 const namespace_decl = namespace.getDecl();
23462358 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);
23482360 return error.AnalysisFail;
23492361 }
23502362
2351 // TODO implement usingnamespace
2352 if (namespace.decls.get(ident_name)) |decl| {
2353 try sema.mod.declareDeclDependency(sema.owner_decl, decl);
2363 if (observe_usingnamespace and namespace.usingnamespace_set.count() != 0) {
2364 const src_file = block.src_decl.namespace.file_scope;
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);
23542424 return decl;
23552425 }
2426
23562427 log.debug("{*} ({s}) depends on non-existence of '{s}' in {*} ({s})", .{
23572428 sema.owner_decl, sema.owner_decl.name, ident_name, namespace_decl, namespace_decl.name,
23582429 });
23592430 // TODO This dependency is too strong. Really, it should only be a dependency
23602431 // on the non-existence of `ident_name` in the namespace. We can lessen the number of
23612432 // 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);
23632434 return null;
23642435}
23652436
......@@ -2727,10 +2798,7 @@ fn analyzeCall(
27272798 // we need to resolve the field type expressions right here, right now, while
27282799 // the child `Sema` is still available, with the AIR instruction map intact,
27292800 // because the field type expressions may reference into it.
2730 if (sema.typeOf(result).zigTypeTag() == .Type) {
2731 const ty = try sema.analyzeAsType(&child_block, call_src, result);
2732 try sema.resolveDeclFields(&child_block, call_src, ty);
2733 }
2801 try sema.resolvePendingTypes(&child_block);
27342802 }
27352803
27362804 break :res2 result;
......@@ -5332,6 +5400,7 @@ fn zirHasField(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileEr
53325400fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
53335401 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
53345402 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
5403 const src = inst_data.src();
53355404 const lhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node };
53365405 const rhs_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node };
53375406 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
53445413 "expected struct, enum, union, or opaque, found '{}'",
53455414 .{container_type},
53465415 );
5347 if (try sema.lookupInNamespace(namespace, decl_name)) |decl| {
5416 if (try sema.lookupInNamespace(block, src, namespace, decl_name, true)) |decl| {
53485417 if (decl.is_pub or decl.namespace.file_scope == block.base.namespace().file_scope) {
53495418 return Air.Inst.Ref.bool_true;
53505419 }
......@@ -8203,7 +8272,7 @@ fn namespaceLookup(
82038272) CompileError!?*Decl {
82048273 const mod = sema.mod;
82058274 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| {
82078276 if (!decl.is_pub and decl.namespace.file_scope != block.getFileScope()) {
82088277 const msg = msg: {
82098278 const msg = try mod.errMsg(&block.base, src, "'{s}' is not marked 'pub'", .{
......@@ -8919,8 +8988,7 @@ fn analyzeDeclVal(
89198988 return result;
89208989}
89218990
8922fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {
8923 try sema.mod.declareDeclDependency(sema.owner_decl, decl);
8991fn ensureDeclAnalyzed(sema: *Sema, decl: *Decl) CompileError!void {
89248992 sema.mod.ensureDeclAnalyzed(decl) catch |err| {
89258993 if (sema.owner_func) |owner_func| {
89268994 owner_func.state = .dependency_failure;
......@@ -8929,6 +8997,11 @@ fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {
89298997 }
89308998 return err;
89318999 };
9000}
9001
9002fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {
9003 try sema.mod.declareDeclDependency(sema.owner_decl, decl);
9004 try sema.ensureDeclAnalyzed(decl);
89329005
89339006 const decl_tv = try decl.typedValue();
89349007 if (decl_tv.val.castTag(.variable)) |payload| {
......@@ -9560,6 +9633,16 @@ pub fn resolveTypeLayout(
95609633 }
95619634}
95629635
9636pub 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
95639646/// `sema` and `block` are expected to be the same ones used for the `Decl`.
95649647pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) !void {
95659648 switch (ty.tag()) {
src/codegen.zig+13-13
......@@ -899,7 +899,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
899899 fn dbgSetPrologueEnd(self: *Self) InnerError!void {
900900 switch (self.debug_output) {
901901 .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);
903903 try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
904904 },
905905 .none => {},
......@@ -909,7 +909,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
909909 fn dbgSetEpilogueBegin(self: *Self) InnerError!void {
910910 switch (self.debug_output) {
911911 .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);
913913 try self.dbgAdvancePCAndLine(self.prev_di_line, self.prev_di_column);
914914 },
915915 .none => {},
......@@ -925,13 +925,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
925925 // It lets you emit single-byte opcodes that add different numbers to
926926 // both the PC and the line number at the same time.
927927 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);
929929 leb128.writeULEB128(dbg_out.dbg_line.writer(), delta_pc) catch unreachable;
930930 if (delta_line != 0) {
931 dbg_out.dbg_line.appendAssumeCapacity(DW.LNS_advance_line);
931 dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.advance_line);
932932 leb128.writeILEB128(dbg_out.dbg_line.writer(), delta_line) catch unreachable;
933933 }
934 dbg_out.dbg_line.appendAssumeCapacity(DW.LNS_copy);
934 dbg_out.dbg_line.appendAssumeCapacity(DW.LNS.copy);
935935 },
936936 .none => {},
937937 }
......@@ -1010,7 +1010,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
10101010 .dwarf => |dbg_out| {
10111011 assert(ty.hasCodeGenBits());
10121012 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
10141014
10151015 const gop = try dbg_out.dbg_info_type_relocs.getOrPut(self.gpa, ty);
10161016 if (!gop.found_existing) {
......@@ -2438,13 +2438,13 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
24382438 .dwarf => |dbg_out| {
24392439 try dbg_out.dbg_info.ensureCapacity(dbg_out.dbg_info.items.len + 3);
24402440 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
24422442 1, // ULEB128 dwarf expression length
24432443 reg.dwarfLocOp(),
24442444 });
24452445 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
2447 dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT_name, DW.FORM_string
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
24482448 },
24492449 .none => {},
24502450 }
......@@ -2467,15 +2467,15 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
24672467 var counting_writer = std.io.countingWriter(std.io.null_writer);
24682468 leb128.writeILEB128(counting_writer.writer(), adjusted_stack_offset) catch unreachable;
24692469
2470 // DW.AT_location, DW.FORM_exprloc
2470 // DW.AT.location, DW.FORM.exprloc
24712471 // ULEB128 dwarf expression length
24722472 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);
24742474 try leb128.writeILEB128(dbg_out.dbg_info.writer(), adjusted_stack_offset);
24752475
24762476 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
2478 dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT_name, DW.FORM_string
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
24792479 },
24802480 else => {},
24812481 }
src/codegen/aarch64.zig+1-1
......@@ -52,7 +52,7 @@ pub const Register = enum(u6) {
5252 }
5353
5454 pub fn dwarfLocOp(self: Register) u8 {
55 return @as(u8, self.id()) + DW.OP_reg0;
55 return @as(u8, self.id()) + DW.OP.reg0;
5656 }
5757};
5858
src/codegen/arm.zig+1-1
......@@ -170,7 +170,7 @@ pub const Register = enum(u5) {
170170 }
171171
172172 pub fn dwarfLocOp(self: Register) u8 {
173 return @as(u8, self.id()) + DW.OP_reg0;
173 return @as(u8, self.id()) + DW.OP.reg0;
174174 }
175175};
176176
src/codegen/riscv64.zig+2-2
......@@ -390,7 +390,7 @@ pub const RawRegister = enum(u5) {
390390 x24, x25, x26, x27, x28, x29, x30, x31,
391391
392392 pub fn dwarfLocOp(reg: RawRegister) u8 {
393 return @enumToInt(reg) + DW.OP_reg0;
393 return @enumToInt(reg) + DW.OP.reg0;
394394 }
395395};
396396
......@@ -424,7 +424,7 @@ pub const Register = enum(u5) {
424424 }
425425
426426 pub fn dwarfLocOp(reg: Register) u8 {
427 return @as(u8, @enumToInt(reg)) + DW.OP_reg0;
427 return @as(u8, @enumToInt(reg)) + DW.OP.reg0;
428428 }
429429};
430430
src/codegen/x86.zig+8-8
......@@ -59,14 +59,14 @@ pub const Register = enum(u8) {
5959
6060 pub fn dwarfLocOp(reg: Register) u8 {
6161 return switch (reg.to32()) {
62 .eax => DW.OP_reg0,
63 .ecx => DW.OP_reg1,
64 .edx => DW.OP_reg2,
65 .ebx => DW.OP_reg3,
66 .esp => DW.OP_reg4,
67 .ebp => DW.OP_reg5,
68 .esi => DW.OP_reg6,
69 .edi => DW.OP_reg7,
62 .eax => DW.OP.reg0,
63 .ecx => DW.OP.reg1,
64 .edx => DW.OP.reg2,
65 .ebx => DW.OP.reg3,
66 .esp => DW.OP.reg4,
67 .ebp => DW.OP.reg5,
68 .esi => DW.OP.reg6,
69 .edi => DW.OP.reg7,
7070 else => unreachable,
7171 };
7272 }
src/codegen/x86_64.zig+17-17
......@@ -115,23 +115,23 @@ pub const Register = enum(u8) {
115115
116116 pub fn dwarfLocOp(self: Register) u8 {
117117 return switch (self.to64()) {
118 .rax => DW.OP_reg0,
119 .rdx => DW.OP_reg1,
120 .rcx => DW.OP_reg2,
121 .rbx => DW.OP_reg3,
122 .rsi => DW.OP_reg4,
123 .rdi => DW.OP_reg5,
124 .rbp => DW.OP_reg6,
125 .rsp => DW.OP_reg7,
126
127 .r8 => DW.OP_reg8,
128 .r9 => DW.OP_reg9,
129 .r10 => DW.OP_reg10,
130 .r11 => DW.OP_reg11,
131 .r12 => DW.OP_reg12,
132 .r13 => DW.OP_reg13,
133 .r14 => DW.OP_reg14,
134 .r15 => DW.OP_reg15,
118 .rax => DW.OP.reg0,
119 .rdx => DW.OP.reg1,
120 .rcx => DW.OP.reg2,
121 .rbx => DW.OP.reg3,
122 .rsi => DW.OP.reg4,
123 .rdi => DW.OP.reg5,
124 .rbp => DW.OP.reg6,
125 .rsp => DW.OP.reg7,
126
127 .r8 => DW.OP.reg8,
128 .r9 => DW.OP.reg9,
129 .r10 => DW.OP.reg10,
130 .r11 => DW.OP.reg11,
131 .r12 => DW.OP.reg12,
132 .r13 => DW.OP.reg13,
133 .r14 => DW.OP.reg14,
134 .r15 => DW.OP.reg15,
135135
136136 else => unreachable,
137137 };
src/link.zig+1-1
......@@ -179,7 +179,7 @@ pub const File = struct {
179179 /// This is where the .debug_info tag for the type is.
180180 off: u32,
181181 /// 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.
183183 relocs: std.ArrayListUnmanaged(u32),
184184 };
185185
src/link/Elf.zig+76-76
......@@ -772,48 +772,48 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
772772 // These are LEB encoded but since the values are all less than 127
773773 // we can simply append these bytes.
774774 const abbrev_buf = [_]u8{
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,
777 DW.FORM_addr, DW.AT_high_pc, DW.FORM_addr,
778 DW.AT_name, DW.FORM_strp, DW.AT_comp_dir,
779 DW.FORM_strp, DW.AT_producer, DW.FORM_strp,
780 DW.AT_language, DW.FORM_data2, 0,
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,
777 DW.FORM.addr, DW.AT.high_pc, DW.FORM.addr,
778 DW.AT.name, DW.FORM.strp, DW.AT.comp_dir,
779 DW.FORM.strp, DW.AT.producer, DW.FORM.strp,
780 DW.AT.language, DW.FORM.data2, 0,
781781 0, // table sentinel
782782 abbrev_subprogram,
783 DW.TAG_subprogram,
784 DW.CHILDREN_yes, // header
785 DW.AT_low_pc,
786 DW.FORM_addr,
787 DW.AT_high_pc,
788 DW.FORM_data4,
789 DW.AT_type,
790 DW.FORM_ref4,
791 DW.AT_name,
792 DW.FORM_string,
783 DW.TAG.subprogram,
784 DW.CHILDREN.yes, // header
785 DW.AT.low_pc,
786 DW.FORM.addr,
787 DW.AT.high_pc,
788 DW.FORM.data4,
789 DW.AT.type,
790 DW.FORM.ref4,
791 DW.AT.name,
792 DW.FORM.string,
793793 0, 0, // table sentinel
794794 abbrev_subprogram_retvoid,
795 DW.TAG_subprogram, DW.CHILDREN_yes, // header
796 DW.AT_low_pc, DW.FORM_addr,
797 DW.AT_high_pc, DW.FORM_data4,
798 DW.AT_name, DW.FORM_string,
795 DW.TAG.subprogram, DW.CHILDREN.yes, // header
796 DW.AT.low_pc, DW.FORM.addr,
797 DW.AT.high_pc, DW.FORM.data4,
798 DW.AT.name, DW.FORM.string,
799799 0,
800800 0, // table sentinel
801801 abbrev_base_type,
802 DW.TAG_base_type,
803 DW.CHILDREN_no, // header
804 DW.AT_encoding,
805 DW.FORM_data1,
806 DW.AT_byte_size,
807 DW.FORM_data1,
808 DW.AT_name,
809 DW.FORM_string, 0, 0, // table sentinel
810 abbrev_pad1, DW.TAG_unspecified_type, DW.CHILDREN_no, // header
802 DW.TAG.base_type,
803 DW.CHILDREN.no, // header
804 DW.AT.encoding,
805 DW.FORM.data1,
806 DW.AT.byte_size,
807 DW.FORM.data1,
808 DW.AT.name,
809 DW.FORM.string, 0, 0, // table sentinel
810 abbrev_pad1, DW.TAG.unspecified_type, DW.CHILDREN.no, // header
811811 0, 0, // table sentinel
812812 abbrev_parameter,
813 DW.TAG_formal_parameter, DW.CHILDREN_no, // header
814 DW.AT_location, DW.FORM_exprloc,
815 DW.AT_type, DW.FORM_ref4,
816 DW.AT_name, DW.FORM_string,
813 DW.TAG.formal_parameter, DW.CHILDREN.no, // header
814 DW.AT.location, DW.FORM.exprloc,
815 DW.AT.type, DW.FORM.ref4,
816 DW.AT.name, DW.FORM.string,
817817 0,
818818 0, // table sentinel
819819 0,
......@@ -897,7 +897,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
897897 const high_pc = text_phdr.p_vaddr + text_phdr.p_memsz;
898898
899899 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
901901 self.writeDwarfAddrAssumeCapacity(&di_buf, low_pc);
902902 self.writeDwarfAddrAssumeCapacity(&di_buf, high_pc);
903903 self.writeDwarfAddrAssumeCapacity(&di_buf, name_strp);
......@@ -906,7 +906,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
906906 // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number:
907907 // http://dwarfstd.org/ShowIssue.php?issue=171115.1
908908 // 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);
910910
911911 if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) {
912912 // 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 {
10301030 di_buf.items.len += ptr_width_bytes; // We will come back and write this.
10311031 const after_header_len = di_buf.items.len;
10321032
1033 const opcode_base = DW.LNS_set_isa + 1;
1033 const opcode_base = DW.LNS.set_isa + 1;
10341034 di_buf.appendSliceAssumeCapacity(&[_]u8{
10351035 1, // minimum_instruction_length
10361036 1, // maximum_operations_per_instruction
......@@ -1041,18 +1041,18 @@ pub fn flushModule(self: *Elf, comp: *Compilation) !void {
10411041
10421042 // Standard opcode lengths. The number of items here is based on `opcode_base`.
10431043 // The value is the number of LEB128 operands the instruction takes.
1044 0, // `DW.LNS_copy`
1045 1, // `DW.LNS_advance_pc`
1046 1, // `DW.LNS_advance_line`
1047 1, // `DW.LNS_set_file`
1048 1, // `DW.LNS_set_column`
1049 0, // `DW.LNS_negate_stmt`
1050 0, // `DW.LNS_set_basic_block`
1051 0, // `DW.LNS_const_add_pc`
1052 1, // `DW.LNS_fixed_advance_pc`
1053 0, // `DW.LNS_set_prologue_end`
1054 0, // `DW.LNS_set_epilogue_begin`
1055 1, // `DW.LNS_set_isa`
1044 0, // `DW.LNS.copy`
1045 1, // `DW.LNS.advance_pc`
1046 1, // `DW.LNS.advance_line`
1047 1, // `DW.LNS.set_file`
1048 1, // `DW.LNS.set_column`
1049 0, // `DW.LNS.negate_stmt`
1050 0, // `DW.LNS.set_basic_block`
1051 0, // `DW.LNS.const_add_pc`
1052 1, // `DW.LNS.fixed_advance_pc`
1053 0, // `DW.LNS.set_prologue_end`
1054 0, // `DW.LNS.set_epilogue_begin`
1055 1, // `DW.LNS.set_isa`
10561056 0, // include_directories (none except the compilation unit cwd)
10571057 });
10581058 // file_names[0]
......@@ -2053,7 +2053,7 @@ fn allocateTextBlock(self: *Elf, text_block: *TextBlock, new_block_size: u64, al
20532053
20542054 // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address
20552055 // 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.
20572057 self.debug_info_header_dirty = true;
20582058 // This becomes dirty for the same reason. We could potentially make this more
20592059 // 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
23032303
23042304 const ptr_width_bytes = self.ptrWidthBytes();
23052305 dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{
2306 DW.LNS_extended_op,
2306 DW.LNS.extended_op,
23072307 ptr_width_bytes + 1,
2308 DW.LNE_set_address,
2308 DW.LNE.set_address,
23092309 });
23102310 // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`.
23112311 assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len);
23122312 dbg_line_buffer.items.len += ptr_width_bytes;
23132313
2314 dbg_line_buffer.appendAssumeCapacity(DW.LNS_advance_line);
2314 dbg_line_buffer.appendAssumeCapacity(DW.LNS.advance_line);
23152315 // This is the "relocatable" relative line offset from the previous function's end curly
23162316 // to this function's begin curly.
23172317 assert(self.getRelocDbgLineOff() == dbg_line_buffer.items.len);
23182318 // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later.
23192319 leb128.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off);
23202320
2321 dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file);
2321 dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_file);
23222322 assert(self.getRelocDbgFileIndex() == dbg_line_buffer.items.len);
23232323 // Once we support more than one source file, this will have the ability to be more
23242324 // than one possible value.
......@@ -2327,7 +2327,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
23272327
23282328 // Emit a line for the begin curly with prologue_end=false. The codegen will
23292329 // 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);
23312331
23322332 // .debug_info subprogram
23332333 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
23442344 // "relocations" and have to be in this fixed place so that functions can be
23452345 // moved in virtual address space.
23462346 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
23482348 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
23502350 if (fn_ret_has_bits) {
23512351 const gop = try dbg_info_type_relocs.getOrPut(self.base.allocator, fn_ret_type);
23522352 if (!gop.found_existing) {
......@@ -2356,9 +2356,9 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
23562356 };
23572357 }
23582358 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
23602360 }
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
23622362
23632363 const res = try codegen.generateFunction(&self.base, decl.srcLoc(), func, air, liveness, &code_buffer, .{
23642364 .dwarf = .{
......@@ -2409,7 +2409,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
24092409 mem.writeInt(u32, ptr, @intCast(u32, local_sym.st_size), target_endian);
24102410 }
24112411
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 });
24132413
24142414 // Now we have the full contents and may allocate a region to store it.
24152415
......@@ -2493,7 +2493,7 @@ pub fn updateFunc(self: *Elf, module: *Module, func: *Module.Fn, air: Air, liven
24932493 const file_pos = debug_line_sect.sh_offset + src_fn.off;
24942494 try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos);
24952495
2496 // .debug_info - End the TAG_subprogram children.
2496 // .debug_info - End the TAG.subprogram children.
24972497 try dbg_info_buffer.append(0);
24982498
24992499 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
25662566 .Bool => {
25672567 try dbg_info_buffer.appendSlice(&[_]u8{
25682568 abbrev_base_type,
2569 DW.ATE_boolean, // DW.AT_encoding , DW.FORM_data1
2570 1, // DW.AT_byte_size, DW.FORM_data1
2571 'b', 'o', 'o', 'l', 0, // DW.AT_name, DW.FORM_string
2569 DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1
2570 1, // DW.AT.byte_size, DW.FORM.data1
2571 'b', 'o', 'o', 'l', 0, // DW.AT.name, DW.FORM.string
25722572 });
25732573 },
25742574 .Int => {
25752575 const info = ty.intInfo(self.base.options.target);
25762576 try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12);
25772577 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);
2578 // DW.AT_encoding, DW.FORM_data1
2578 // DW.AT.encoding, DW.FORM.data1
25792579 dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) {
2580 .signed => DW.ATE_signed,
2581 .unsigned => DW.ATE_unsigned,
2580 .signed => DW.ATE.signed,
2581 .unsigned => DW.ATE.unsigned,
25822582 });
2583 // DW.AT_byte_size, DW.FORM_data1
2583 // DW.AT.byte_size, DW.FORM.data1
25842584 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
25862586 try dbg_info_buffer.writer().print("{}\x00", .{ty});
25872587 },
25882588 .Optional => {
25892589 if (ty.isPtrLikeOptional()) {
25902590 try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12);
25912591 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);
2592 // DW.AT_encoding, DW.FORM_data1
2593 dbg_info_buffer.appendAssumeCapacity(DW.ATE_address);
2594 // DW.AT_byte_size, DW.FORM_data1
2592 // DW.AT.encoding, DW.FORM.data1
2593 dbg_info_buffer.appendAssumeCapacity(DW.ATE.address);
2594 // DW.AT.byte_size, DW.FORM.data1
25952595 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
25972597 try dbg_info_buffer.writer().print("{}\x00", .{ty});
25982598 } else {
25992599 log.err("TODO implement .debug_info for type '{}'", .{ty});
......@@ -3034,7 +3034,7 @@ fn archPtrWidthBytes(self: Elf) u8 {
30343034/// The reloc offset for the virtual address of a function in its Line Number Program.
30353035/// Size is a virtual address integer.
30363036const 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.
30383038/// Size is a virtual address integer.
30393039const dbg_info_low_pc_reloc_index = 1;
30403040
......@@ -3060,7 +3060,7 @@ fn dbgLineNeededHeaderBytes(self: Elf) u32 {
30603060 const root_src_dir_path_len = if (self.base.options.module.?.root_pkg.root_src_directory.path) |p| p.len else 1; // "."
30613061 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +
30623062 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
30643064 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.
30653065 root_src_dir_path_len +
30663066 self.base.options.module.?.root_pkg.root_src_path.len);
......@@ -3088,8 +3088,8 @@ fn pwriteDbgLineNops(
30883088 const tracy = trace(@src());
30893089 defer tracy.end();
30903090
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 };
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 };
30933093 var vecs: [512]std.os.iovec_const = undefined;
30943094 var vec_index: usize = 0;
30953095 {
src/link/MachO/DebugSymbols.zig+70-70
......@@ -93,7 +93,7 @@ const abbrev_parameter = 6;
9393/// The reloc offset for the virtual address of a function in its Line Number Program.
9494/// Size is a virtual address integer.
9595const 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.
9797/// Size is a virtual address integer.
9898const dbg_info_low_pc_reloc_index = 1;
9999
......@@ -299,40 +299,40 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt
299299 // These are LEB encoded but since the values are all less than 127
300300 // we can simply append these bytes.
301301 const abbrev_buf = [_]u8{
302 abbrev_compile_unit, DW.TAG_compile_unit, DW.CHILDREN_yes, // header
303 DW.AT_stmt_list, DW.FORM_sec_offset, // offset
304 DW.AT_low_pc, DW.FORM_addr,
305 DW.AT_high_pc, DW.FORM_addr,
306 DW.AT_name, DW.FORM_strp,
307 DW.AT_comp_dir, DW.FORM_strp,
308 DW.AT_producer, DW.FORM_strp,
309 DW.AT_language, DW.FORM_data2,
302 abbrev_compile_unit, DW.TAG.compile_unit, DW.CHILDREN.yes, // header
303 DW.AT.stmt_list, DW.FORM.sec_offset, // offset
304 DW.AT.low_pc, DW.FORM.addr,
305 DW.AT.high_pc, DW.FORM.addr,
306 DW.AT.name, DW.FORM.strp,
307 DW.AT.comp_dir, DW.FORM.strp,
308 DW.AT.producer, DW.FORM.strp,
309 DW.AT.language, DW.FORM.data2,
310310 0, 0, // table sentinel
311 abbrev_subprogram, DW.TAG_subprogram, DW.CHILDREN_yes, // header
312 DW.AT_low_pc, DW.FORM_addr, // start VM address
313 DW.AT_high_pc, DW.FORM_data4,
314 DW.AT_type, DW.FORM_ref4,
315 DW.AT_name, DW.FORM_string,
316 DW.AT_decl_line, DW.FORM_data4,
317 DW.AT_decl_file, DW.FORM_data1,
311 abbrev_subprogram, DW.TAG.subprogram, DW.CHILDREN.yes, // header
312 DW.AT.low_pc, DW.FORM.addr, // start VM address
313 DW.AT.high_pc, DW.FORM.data4,
314 DW.AT.type, DW.FORM.ref4,
315 DW.AT.name, DW.FORM.string,
316 DW.AT.decl_line, DW.FORM.data4,
317 DW.AT.decl_file, DW.FORM.data1,
318318 0, 0, // table sentinel
319319 abbrev_subprogram_retvoid,
320 DW.TAG_subprogram, DW.CHILDREN_yes, // header
321 DW.AT_low_pc, DW.FORM_addr,
322 DW.AT_high_pc, DW.FORM_data4,
323 DW.AT_name, DW.FORM_string,
324 DW.AT_decl_line, DW.FORM_data4,
325 DW.AT_decl_file, DW.FORM_data1,
320 DW.TAG.subprogram, DW.CHILDREN.yes, // header
321 DW.AT.low_pc, DW.FORM.addr,
322 DW.AT.high_pc, DW.FORM.data4,
323 DW.AT.name, DW.FORM.string,
324 DW.AT.decl_line, DW.FORM.data4,
325 DW.AT.decl_file, DW.FORM.data1,
326326 0, 0, // table sentinel
327 abbrev_base_type, DW.TAG_base_type, DW.CHILDREN_no, // header
328 DW.AT_encoding, DW.FORM_data1, DW.AT_byte_size,
329 DW.FORM_data1, DW.AT_name, DW.FORM_string,
327 abbrev_base_type, DW.TAG.base_type, DW.CHILDREN.no, // header
328 DW.AT.encoding, DW.FORM.data1, DW.AT.byte_size,
329 DW.FORM.data1, DW.AT.name, DW.FORM.string,
330330 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
332332 0, 0, // table sentinel
333 abbrev_parameter, DW.TAG_formal_parameter, DW.CHILDREN_no, // header
334 DW.AT_location, DW.FORM_exprloc, DW.AT_type,
335 DW.FORM_ref4, DW.AT_name, DW.FORM_string,
333 abbrev_parameter, DW.TAG.formal_parameter, DW.CHILDREN.no, // header
334 DW.AT.location, DW.FORM.exprloc, DW.AT.type,
335 DW.FORM.ref4, DW.AT.name, DW.FORM.string,
336336 0, 0, // table sentinel
337337 0, 0, 0, // section sentinel
338338 };
......@@ -397,7 +397,7 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt
397397 const high_pc = text_section.addr + text_section.size;
398398
399399 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
401401 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), low_pc);
402402 mem.writeIntLittle(u64, di_buf.addManyAsArrayAssumeCapacity(8), high_pc);
403403 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
406406 // We are still waiting on dwarf-std.org to assign DW_LANG_Zig a number:
407407 // http://dwarfstd.org/ShowIssue.php?issue=171115.1
408408 // 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);
410410
411411 if (di_buf.items.len > first_dbg_info_decl.dbg_info_off) {
412412 // 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
514514 di_buf.items.len += @sizeOf(u32); // We will come back and write this.
515515 const after_header_len = di_buf.items.len;
516516
517 const opcode_base = DW.LNS_set_isa + 1;
517 const opcode_base = DW.LNS.set_isa + 1;
518518 di_buf.appendSliceAssumeCapacity(&[_]u8{
519519 1, // minimum_instruction_length
520520 1, // maximum_operations_per_instruction
......@@ -525,18 +525,18 @@ pub fn flushModule(self: *DebugSymbols, allocator: *Allocator, options: link.Opt
525525
526526 // Standard opcode lengths. The number of items here is based on `opcode_base`.
527527 // The value is the number of LEB128 operands the instruction takes.
528 0, // `DW.LNS_copy`
529 1, // `DW.LNS_advance_pc`
530 1, // `DW.LNS_advance_line`
531 1, // `DW.LNS_set_file`
532 1, // `DW.LNS_set_column`
533 0, // `DW.LNS_negate_stmt`
534 0, // `DW.LNS_set_basic_block`
535 0, // `DW.LNS_const_add_pc`
536 1, // `DW.LNS_fixed_advance_pc`
537 0, // `DW.LNS_set_prologue_end`
538 0, // `DW.LNS_set_epilogue_begin`
539 1, // `DW.LNS_set_isa`
528 0, // `DW.LNS.copy`
529 1, // `DW.LNS.advance_pc`
530 1, // `DW.LNS.advance_line`
531 1, // `DW.LNS.set_file`
532 1, // `DW.LNS.set_column`
533 0, // `DW.LNS.negate_stmt`
534 0, // `DW.LNS.set_basic_block`
535 0, // `DW.LNS.const_add_pc`
536 1, // `DW.LNS.fixed_advance_pc`
537 0, // `DW.LNS.set_prologue_end`
538 0, // `DW.LNS.set_epilogue_begin`
539 1, // `DW.LNS.set_isa`
540540 0, // include_directories (none except the compilation unit cwd)
541541 });
542542 // file_names[0]
......@@ -876,22 +876,22 @@ pub fn initDeclDebugBuffers(
876876 const line_off = @intCast(u28, decl.src_line + func.lbrace_line);
877877
878878 dbg_line_buffer.appendSliceAssumeCapacity(&[_]u8{
879 DW.LNS_extended_op,
879 DW.LNS.extended_op,
880880 @sizeOf(u64) + 1,
881 DW.LNE_set_address,
881 DW.LNE.set_address,
882882 });
883883 // This is the "relocatable" vaddr, corresponding to `code_buffer` index `0`.
884884 assert(dbg_line_vaddr_reloc_index == dbg_line_buffer.items.len);
885885 dbg_line_buffer.items.len += @sizeOf(u64);
886886
887 dbg_line_buffer.appendAssumeCapacity(DW.LNS_advance_line);
887 dbg_line_buffer.appendAssumeCapacity(DW.LNS.advance_line);
888888 // This is the "relocatable" relative line offset from the previous function's end curly
889889 // to this function's begin curly.
890890 assert(getRelocDbgLineOff() == dbg_line_buffer.items.len);
891891 // Here we use a ULEB128-fixed-4 to make sure this field can be overwritten later.
892892 leb.writeUnsignedFixed(4, dbg_line_buffer.addManyAsArrayAssumeCapacity(4), line_off);
893893
894 dbg_line_buffer.appendAssumeCapacity(DW.LNS_set_file);
894 dbg_line_buffer.appendAssumeCapacity(DW.LNS.set_file);
895895 assert(getRelocDbgFileIndex() == dbg_line_buffer.items.len);
896896 // Once we support more than one source file, this will have the ability to be more
897897 // than one possible value.
......@@ -900,7 +900,7 @@ pub fn initDeclDebugBuffers(
900900
901901 // Emit a line for the begin curly with prologue_end=false. The codegen will
902902 // 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);
904904
905905 // .debug_info subprogram
906906 const decl_name_with_null = decl.name[0 .. mem.lenZ(decl.name) + 1];
......@@ -917,9 +917,9 @@ pub fn initDeclDebugBuffers(
917917 // "relocations" and have to be in this fixed place so that functions can be
918918 // moved in virtual address space.
919919 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
921921 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
923923 if (fn_ret_has_bits) {
924924 const gop = try dbg_info_type_relocs.getOrPut(allocator, fn_ret_type);
925925 if (!gop.found_existing) {
......@@ -929,11 +929,11 @@ pub fn initDeclDebugBuffers(
929929 };
930930 }
931931 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
933933 }
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
936 dbg_info_buffer.appendAssumeCapacity(file_index); // DW.AT_decl_file, DW.FORM_data1
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
936 dbg_info_buffer.appendAssumeCapacity(file_index); // DW.AT.decl_file, DW.FORM.data1
937937 },
938938 else => {
939939 // TODO implement .debug_info for global variables
......@@ -985,16 +985,16 @@ pub fn commitDeclDebugInfo(
985985 {
986986 // Advance line and PC.
987987 // 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);
989989 try leb.writeULEB128(dbg_line_buffer.writer(), text_block.size);
990990
991 try dbg_line_buffer.append(DW.LNS_advance_line);
991 try dbg_line_buffer.append(DW.LNS.advance_line);
992992 const func = decl.val.castTag(.function).?.data;
993993 const line_off = @intCast(u28, func.rbrace_line - func.lbrace_line);
994994 try leb.writeULEB128(dbg_line_buffer.writer(), line_off);
995995 }
996996
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 });
998998
999999 // Now we have the full contents and may allocate a region to store it.
10001000
......@@ -1075,7 +1075,7 @@ pub fn commitDeclDebugInfo(
10751075 const file_pos = debug_line_sect.offset + src_fn.off;
10761076 try self.pwriteDbgLineNops(prev_padding_size, dbg_line_buffer.items, next_padding_size, file_pos);
10771077
1078 // .debug_info - End the TAG_subprogram children.
1078 // .debug_info - End the TAG.subprogram children.
10791079 try dbg_info_buffer.append(0);
10801080 },
10811081 else => {},
......@@ -1128,27 +1128,27 @@ fn addDbgInfoType(
11281128 .Bool => {
11291129 try dbg_info_buffer.appendSlice(&[_]u8{
11301130 abbrev_base_type,
1131 DW.ATE_boolean, // DW.AT_encoding , DW.FORM_data1
1132 1, // DW.AT_byte_size, DW.FORM_data1
1131 DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1
1132 1, // DW.AT.byte_size, DW.FORM.data1
11331133 'b',
11341134 'o',
11351135 'o',
11361136 'l',
1137 0, // DW.AT_name, DW.FORM_string
1137 0, // DW.AT.name, DW.FORM.string
11381138 });
11391139 },
11401140 .Int => {
11411141 const info = ty.intInfo(target);
11421142 try dbg_info_buffer.ensureCapacity(dbg_info_buffer.items.len + 12);
11431143 dbg_info_buffer.appendAssumeCapacity(abbrev_base_type);
1144 // DW.AT_encoding, DW.FORM_data1
1144 // DW.AT.encoding, DW.FORM.data1
11451145 dbg_info_buffer.appendAssumeCapacity(switch (info.signedness) {
1146 .signed => DW.ATE_signed,
1147 .unsigned => DW.ATE_unsigned,
1146 .signed => DW.ATE.signed,
1147 .unsigned => DW.ATE.unsigned,
11481148 });
1149 // DW.AT_byte_size, DW.FORM_data1
1149 // DW.AT.byte_size, DW.FORM.data1
11501150 dbg_info_buffer.appendAssumeCapacity(@intCast(u8, ty.abiSize(target)));
1151 // DW.AT_name, DW.FORM_string
1151 // DW.AT.name, DW.FORM.string
11521152 try dbg_info_buffer.writer().print("{}\x00", .{ty});
11531153 },
11541154 else => {
......@@ -1306,7 +1306,7 @@ fn dbgLineNeededHeaderBytes(self: DebugSymbols, module: *Module) u32 {
13061306 const root_src_dir_path_len = if (module.root_pkg.root_src_directory.path) |p| p.len else 1; // "."
13071307 return @intCast(u32, 53 + directory_entry_format_count * 2 + file_name_entry_format_count * 2 +
13081308 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
13101310 // because of a workaround for readelf and gdb failing to understand DWARFv5 correctly.
13111311 root_src_dir_path_len +
13121312 module.root_pkg.root_src_path.len);
......@@ -1332,8 +1332,8 @@ fn pwriteDbgLineNops(
13321332 const tracy = trace(@src());
13331333 defer tracy.end();
13341334
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 };
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 };
13371337 var vecs: [32]std.os.iovec_const = undefined;
13381338 var vec_index: usize = 0;
13391339 {
src/link/MachO/Object.zig+2-2
......@@ -836,8 +836,8 @@ pub fn parseDebugInfo(self: *Object, allocator: *Allocator) !void {
836836 },
837837 else => |e| return e,
838838 };
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);
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);
841841
842842 self.debug_info = debug_info;
843843 self.tu_name = try allocator.dupe(u8, name);
test/behavior.zig+2-1
......@@ -10,6 +10,7 @@ test {
1010 _ = @import("behavior/if.zig");
1111 _ = @import("behavior/cast.zig");
1212 _ = @import("behavior/array.zig");
13 _ = @import("behavior/usingnamespace.zig");
1314
1415 if (!builtin.zig_is_stage2) {
1516 // Tests that only pass for stage1.
......@@ -148,7 +149,7 @@ test {
148149 _ = @import("behavior/undefined.zig");
149150 _ = @import("behavior/underscore.zig");
150151 _ = @import("behavior/union.zig");
151 _ = @import("behavior/usingnamespace.zig");
152 _ = @import("behavior/usingnamespace_stage1.zig");
152153 _ = @import("behavior/var_args.zig");
153154 _ = @import("behavior/vector.zig");
154155 _ = @import("behavior/void.zig");
test/behavior/eval.zig-6
......@@ -125,12 +125,6 @@ test "pointer to type" {
125125 }
126126}
127127
128test "no undeclared identifier error in unanalyzed branches" {
129 if (false) {
130 lol_this_doesnt_exist = nonsense;
131 }
132}
133
134128test "a type constructed in a global expression" {
135129 var l: List = undefined;
136130 l.array[0] = 10;
test/behavior/usingnamespace.zig+7-16
......@@ -1,22 +1,13 @@
11const std = @import("std");
22
3fn Foo(comptime T: type) type {
4 return struct {
5 usingnamespace T;
6 };
7}
8
9test "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}
3const A = struct {
4 pub const B = bool;
5};
156
16usingnamespace struct {
17 pub const foo = 42;
7const C = struct {
8 usingnamespace A;
189};
1910
20test "usingnamespace does not redeclare an imported variable" {
21 comptime try std.testing.expect(foo == 42);
11test "basic usingnamespace" {
12 try std.testing.expect(C.B == bool);
2213}
test/behavior/usingnamespace_stage1.zig created+22
......@@ -0,0 +1,22 @@
1const std = @import("std");
2
3fn Foo(comptime T: type) type {
4 return struct {
5 usingnamespace T;
6 };
7}
8
9test "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
16usingnamespace struct {
17 pub const foo = 42;
18};
19
20test "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 {
88468846 , &[_][]const u8{
88478847 "error: invalid operands to binary expression: 'f32' and 'f32'",
88488848 });
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 });
88498859}