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(...@@ -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 }
64196422
6420 // Decl references happen by name rather than ZIR index so that when unrelated6423 // 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}
1005410057
10055/// Local variables shadowing detection, including function parameters and primitives.10058/// Local variables shadowing detection, including function parameters.
10056fn detectLocalShadowing(10059fn 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 it365 /// 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,
368370
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 {
10081010
1009 anon_decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{},1011 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
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);
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
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);
32823311
3283 if (decl.is_exported) {3312 if (decl.is_exported) {
3284 const export_src = src; // TODO point to the export token3313 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
34943523
3495 // zig fmt: off3524 // 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: on3529 // 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);
35383570
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 decl3586 0 => true, // comptime or usingnamespace decl
3552 1 => blk: {3587 1 => blk: {
3553 // test decl with no name. Skip the part where we check against3588 // 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
35873623
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.
60preallocated_new_func: ?*Module.Fn = null,60preallocated_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
62const std = @import("std");65const std = @import("std");
63const mem = std.mem;66const 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}
9599
...@@ -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}
914920
...@@ -1198,7 +1204,9 @@ fn zirUnionDecl(...@@ -1198,7 +1204,9 @@ fn zirUnionDecl(
11981204
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);
12001206
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}
12041212
...@@ -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}
23252333
2326fn lookupIdentifier(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, name: []const u8) !*Decl {2334fn 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}
23372344
2338/// This looks up a member of a specific namespace. It is affected by `usingnamespace` but2345/// 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.
2340fn lookupInNamespace(2347fn 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 }
23502362
2351 // TODO implement usingnamespace2363 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 dependency2430 // 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 of2431 // 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}
23652436
...@@ -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, while2798 // 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 }
27352803
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
5332fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {5400fn 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}
89218990
8922fn analyzeDeclRef(sema: *Sema, decl: *Decl) CompileError!Air.Inst.Ref {8991fn 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
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
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}
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
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`.
9564pub fn resolveDeclFields(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, ty: Type) !void {9647pub 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 to925 // 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_ref41013 try dbg_out.dbg_info.resize(index + 4); // DW.AT.type, DW.FORM.ref4
10141014
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_exprloc2441 dbg_out.dbg_info.appendSliceAssumeCapacity(&[2]u8{ // DW.AT.location, DW.FORM.exprloc
2442 1, // ULEB128 dwarf expression length2442 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_ref42446 try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
2447 dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT_name, DW.FORM_string2447 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;
24692469
2470 // DW.AT_location, DW.FORM_exprloc2470 // DW.AT.location, DW.FORM.exprloc
2471 // ULEB128 dwarf expression length2471 // 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);
24752475
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_ref42477 try self.addDbgInfoTypeReloc(ty); // DW.AT.type, DW.FORM.ref4
2478 dbg_out.dbg_info.appendSliceAssumeCapacity(name_with_null); // DW.AT_name, DW.FORM_string2478 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 }
5353
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};
5858
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 }
171171
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};
176176
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,
391391
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};
396396
...@@ -424,7 +424,7 @@ pub const Register = enum(u5) {...@@ -424,7 +424,7 @@ pub const Register = enum(u5) {
424 }424 }
425425
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};
430430
src/codegen/x86.zig+8-8
...@@ -59,14 +59,14 @@ pub const Register = enum(u8) {...@@ -59,14 +59,14 @@ pub const Register = enum(u8) {
5959
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) {
115115
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,
126126
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,
135135
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 };
185185
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 127772 // 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, // header775 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 sentinel781 0, // table sentinel
782 abbrev_subprogram,782 abbrev_subprogram,
783 DW.TAG_subprogram,783 DW.TAG.subprogram,
784 DW.CHILDREN_yes, // header784 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 sentinel793 0, 0, // table sentinel
794 abbrev_subprogram_retvoid,794 abbrev_subprogram_retvoid,
795 DW.TAG_subprogram, DW.CHILDREN_yes, // header795 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 sentinel800 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, // header803 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 sentinel809 DW.FORM.string, 0, 0, // table sentinel
810 abbrev_pad1, DW.TAG_unspecified_type, DW.CHILDREN_no, // header810 abbrev_pad1, DW.TAG.unspecified_type, DW.CHILDREN.no, // header
811 0, 0, // table sentinel811 0, 0, // table sentinel
812 abbrev_parameter,812 abbrev_parameter,
813 DW.TAG_formal_parameter, DW.CHILDREN_no, // header813 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 sentinel818 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;
898898
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_offset900 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.1907 // 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);
910910
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;
10321032
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_length1035 1, // minimum_instruction_length
1036 1, // maximum_operations_per_instruction1036 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 {
10411041
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
20532053
2054 // The .debug_info section has `low_pc` and `high_pc` values which is the virtual address2054 // 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 more2058 // 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 to2059 // 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
23032303
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;
23132313
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 curly2315 // 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);
23202320
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 more2323 // 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
23272327
2328 // Emit a line for the begin curly with prologue_end=false. The codegen will2328 // 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);
23312331
2332 // .debug_info subprogram2332 // .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 be2344 // "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_addr2347 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_data42349 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_ref42359 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_string2361 dbg_info_buffer.appendSliceAssumeCapacity(decl_name_with_null); // DW.AT.name, DW.FORM.string
23622362
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 }
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
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.
24152415
...@@ -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);
24952495
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);
24982498
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_data12569 DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1
2570 1, // DW.AT_byte_size, DW.FORM_data12570 1, // DW.AT.byte_size, DW.FORM.data1
2571 'b', 'o', 'o', 'l', 0, // DW.AT_name, DW.FORM_string2571 '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_data12578 // 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_data12583 // 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_string2585 // 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_data12592 // 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_data12594 // 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_string2596 // 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.
3036const dbg_line_vaddr_reloc_index = 3;3036const 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.
3039const dbg_info_low_pc_reloc_index = 1;3039const dbg_info_low_pc_reloc_index = 1;
30403040
...@@ -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 like3063 // 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();
30903090
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.
95const dbg_line_vaddr_reloc_index = 3;95const 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.
98const dbg_info_low_pc_reloc_index = 1;98const dbg_info_low_pc_reloc_index = 1;
9999
...@@ -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 127299 // 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, // header302 abbrev_compile_unit, DW.TAG.compile_unit, DW.CHILDREN.yes, // header
303 DW.AT_stmt_list, DW.FORM_sec_offset, // offset303 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 sentinel310 0, 0, // table sentinel
311 abbrev_subprogram, DW.TAG_subprogram, DW.CHILDREN_yes, // header311 abbrev_subprogram, DW.TAG.subprogram, DW.CHILDREN.yes, // header
312 DW.AT_low_pc, DW.FORM_addr, // start VM address312 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 sentinel318 0, 0, // table sentinel
319 abbrev_subprogram_retvoid,319 abbrev_subprogram_retvoid,
320 DW.TAG_subprogram, DW.CHILDREN_yes, // header320 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 sentinel326 0, 0, // table sentinel
327 abbrev_base_type, DW.TAG_base_type, DW.CHILDREN_no, // header327 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 sentinel330 0, 0, // table sentinel
331 abbrev_pad1, DW.TAG_unspecified_type, DW.CHILDREN_no, // header331 abbrev_pad1, DW.TAG.unspecified_type, DW.CHILDREN.no, // header
332 0, 0, // table sentinel332 0, 0, // table sentinel
333 abbrev_parameter, DW.TAG_formal_parameter, DW.CHILDREN_no, // header333 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 sentinel336 0, 0, // table sentinel
337 0, 0, 0, // section sentinel337 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;
398398
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_offset400 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.1407 // 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);
410410
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;
516516
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_length519 1, // minimum_instruction_length
520 1, // maximum_operations_per_instruction520 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
525525
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);
877877
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);
886886
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 curly888 // 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);
893893
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 more896 // 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(
900900
901 // Emit a line for the begin curly with prologue_end=false. The codegen will901 // 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);
904904
905 // .debug_info subprogram905 // .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 be917 // "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_addr920 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_data4922 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_ref4932 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_string934 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_data4935 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_data1936 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 variables939 // 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);
990990
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 }
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
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.
10001000
...@@ -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);
10771077
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_data11131 DW.ATE.boolean, // DW.AT.encoding , DW.FORM.data1
1132 1, // DW.AT_byte_size, DW.FORM_data11132 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_string1137 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_data11144 // 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_data11149 // 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_string1151 // 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 like1309 // 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();
13341334
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);
841841
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");
1314
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}
127127
128test "no undeclared identifier error in unanalyzed branches" {
129 if (false) {
130 lol_this_doesnt_exist = nonsense;
131 }
132}
133
134test "a type constructed in a global expression" {128test "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 @@
1const std = @import("std");1const std = @import("std");
22
3fn Foo(comptime T: type) type {3const A = struct {
4 return struct {4 pub const B = bool;
5 usingnamespace T;5};
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}
156
16usingnamespace struct {7const C = struct {
17 pub const foo = 42;8 usingnamespace A;
18};9};
1910
20test "usingnamespace does not redeclare an imported variable" {11test "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 @@
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 {...@@ -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}