authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-12 16:44:51-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-15 19:06:39-07:00
logbcfebb4b2b17dcac445fc5dedbbd259cc8c2f306
tree48950201c23c8ccde48e2e31c91464c7e96e6163
parent429cd2b5dd27bec15a4a3351114ce1bcd12d8d01

stage2: improvements aimed at std lib integration

* AstGen: emit decl lookup ZIR instructions rather than directly looking up decls in AstGen. This is necessary because we want to reuse the same immutable ZIR code for multiple generic instantiations (and comptime function calls). * AstGen: fix using members_len instead of fields_len for struct decls. * structs: the struct_decl ZIR instruction is now also a block. This is so that the type expressions, default field value expressions, and alignment expressions can be evaluated in a scope that contains the decls from the struct namespace itself. * Add "std" and "builtin" packages to the builtin package. * Don't try to build glibc, musl, or mingw-w64 when using `-ofmt=c`. * builtin.zig is generated without `usingnamespace`. * builtin.zig takes advantage of `std.zig.fmtId` for CPU features. * A first pass at implementing `usingnamespace`. It's problematic and should either be deleted, or polished, before merging this branch. * Sema: allow explicitly specifying the namespace in which to look up Decls. This is used by `struct_decl` in order to put the decls from the struct namespace itself in scope when evaluating the type expressions, default value expressions, and alignment expressions. * Module: fix `analyzeNamespace` assuming that it is the top-level root declaration node. * Sema: implement comptime and runtime cmp operator. * Sema: implement peer type resolution for enums and enum literals. * Pull in the changes from master branch: 262e09c482d98a78531c049a18b7f24146fe157f. * ZIR: complete out simple_ptr_type debug printing

12 files changed, 475 insertions(+), 153 deletions(-)

BRANCH_TODO+5
......@@ -1,4 +1,8 @@
11 * get rid of failed_root_src_file
2 * handle decl collision with usingnamespace
3 * the decl doing the looking up needs to create a decl dependency
4 on each usingnamespace decl
5 * handle usingnamespace cycles
26
37
48 const container_name_hash: Scope.NameHash = if (found_pkg) |pkg|
......@@ -94,3 +98,4 @@ fn getAnonTypeName(mod: *Module, scope: *Scope, base_token: std.zig.ast.TokenInd
9498 return std.fmt.allocPrint(mod.gpa, "{s}:{d}:{d}", .{ base_name, loc.line, loc.column });
9599}
96100
101
build.zig+1-1
......@@ -1,5 +1,5 @@
1const builtin = @import("builtin");
21const std = @import("std");
2const builtin = std.builtin;
33const Builder = std.build.Builder;
44const tests = @import("test/tests.zig");
55const BufMap = std.BufMap;
src/AstGen.zig+42-22
......@@ -1254,6 +1254,8 @@ fn blockExprStmts(
12541254 .coerce_result_ptr,
12551255 .decl_ref,
12561256 .decl_val,
1257 .decl_ref_named,
1258 .decl_val_named,
12571259 .load,
12581260 .div,
12591261 .elem_ptr,
......@@ -1817,7 +1819,7 @@ pub fn structDeclInner(
18171819 tag: zir.Inst.Tag,
18181820) InnerError!zir.Inst.Ref {
18191821 if (container_decl.ast.members.len == 0) {
1820 return gz.addPlNode(tag, node, zir.Inst.StructDecl{ .fields_len = 0 });
1822 return gz.addPlNode(tag, node, zir.Inst.StructDecl{ .fields_len = 0, .body_len = 0 });
18211823 }
18221824
18231825 const astgen = gz.astgen;
......@@ -1826,12 +1828,21 @@ pub fn structDeclInner(
18261828 const tree = gz.tree();
18271829 const node_tags = tree.nodes.items(.tag);
18281830
1831 // The struct_decl instruction introduces a scope in which the decls of the struct
1832 // are in scope, so that field types, alignments, and default value expressions
1833 // can refer to decls within the struct itself.
1834 var block_scope: GenZir = .{
1835 .parent = scope,
1836 .astgen = astgen,
1837 .force_comptime = true,
1838 };
1839 defer block_scope.instructions.deinit(gpa);
1840
1841 // We don't know which members are fields until we iterate, so cannot do
1842 // an accurate ensureCapacity yet.
18291843 var fields_data = ArrayListUnmanaged(u32){};
18301844 defer fields_data.deinit(gpa);
18311845
1832 // field_name and field_type are both mandatory
1833 try fields_data.ensureCapacity(gpa, container_decl.ast.members.len * 2);
1834
18351846 // We only need this if there are greater than 16 fields.
18361847 var bit_bag = ArrayListUnmanaged(u32){};
18371848 defer bit_bag.deinit(gpa);
......@@ -1857,7 +1868,7 @@ pub fn structDeclInner(
18571868 const field_name = try gz.identAsString(member.ast.name_token);
18581869 fields_data.appendAssumeCapacity(field_name);
18591870
1860 const field_type = try typeExpr(gz, scope, member.ast.type_expr);
1871 const field_type = try typeExpr(&block_scope, &block_scope.base, member.ast.type_expr);
18611872 fields_data.appendAssumeCapacity(@enumToInt(field_type));
18621873
18631874 const have_align = member.ast.align_expr != 0;
......@@ -1867,31 +1878,40 @@ pub fn structDeclInner(
18671878 (@as(u32, @boolToInt(have_value)) << 31);
18681879
18691880 if (have_align) {
1870 const align_inst = try comptimeExpr(gz, scope, .{ .ty = .u32_type }, member.ast.align_expr);
1881 const align_inst = try expr(&block_scope, &block_scope.base, .{ .ty = .u32_type }, member.ast.align_expr);
18711882 fields_data.appendAssumeCapacity(@enumToInt(align_inst));
18721883 }
18731884 if (have_value) {
1874 const default_inst = try comptimeExpr(gz, scope, .{ .ty = field_type }, member.ast.value_expr);
1885 const default_inst = try expr(&block_scope, &block_scope.base, .{ .ty = field_type }, member.ast.value_expr);
18751886 fields_data.appendAssumeCapacity(@enumToInt(default_inst));
18761887 }
18771888
18781889 field_index += 1;
18791890 }
18801891 if (field_index == 0) {
1881 return gz.addPlNode(tag, node, zir.Inst.StructDecl{ .fields_len = 0 });
1892 return gz.addPlNode(tag, node, zir.Inst.StructDecl{ .fields_len = 0, .body_len = 0 });
18821893 }
18831894 const empty_slot_count = 16 - (field_index % 16);
18841895 cur_bit_bag >>= @intCast(u5, empty_slot_count * 2);
18851896
1886 const result = try gz.addPlNode(tag, node, zir.Inst.StructDecl{
1887 .fields_len = @intCast(u32, container_decl.ast.members.len),
1888 });
1897 const decl_inst = try gz.addBlock(tag, node);
1898 try gz.instructions.append(gpa, decl_inst);
1899 _ = try block_scope.addBreak(.break_inline, decl_inst, .void_value);
1900
18891901 try astgen.extra.ensureCapacity(gpa, astgen.extra.items.len +
1890 bit_bag.items.len + 1 + fields_data.items.len);
1902 @typeInfo(zir.Inst.StructDecl).Struct.fields.len +
1903 bit_bag.items.len + 1 + fields_data.items.len +
1904 block_scope.instructions.items.len);
1905 const zir_datas = astgen.instructions.items(.data);
1906 zir_datas[decl_inst].pl_node.payload_index = astgen.addExtraAssumeCapacity(zir.Inst.StructDecl{
1907 .body_len = @intCast(u32, block_scope.instructions.items.len),
1908 .fields_len = @intCast(u32, field_index),
1909 });
1910 astgen.extra.appendSliceAssumeCapacity(block_scope.instructions.items);
18911911 astgen.extra.appendSliceAssumeCapacity(bit_bag.items); // Likely empty.
18921912 astgen.extra.appendAssumeCapacity(cur_bit_bag);
18931913 astgen.extra.appendSliceAssumeCapacity(fields_data.items);
1894 return result;
1914 return astgen.indexToRef(decl_inst);
18951915}
18961916
18971917fn containerDecl(
......@@ -3722,16 +3742,16 @@ fn identifier(
37223742 };
37233743 }
37243744
3725 const decl = mod.lookupIdentifier(scope, ident_name) orelse {
3726 // TODO insert a "dependency on the non-existence of a decl" here to make this
3727 // compile error go away when the decl is introduced. This data should be in a global
3728 // sparse map since it is only relevant when a compile error occurs.
3729 return mod.failNode(scope, ident, "use of undeclared identifier '{s}'", .{ident_name});
3730 };
3731 const decl_index = try mod.declareDeclDependency(astgen.decl, decl);
3745 // We can't look up Decls until Sema because the same ZIR code is supposed to be
3746 // used for multiple generic instantiations, and this may refer to a different Decl
3747 // depending on the scope, determined by the generic instantiation.
3748 const str_index = try gz.identAsString(ident_token);
37323749 switch (rl) {
3733 .ref, .none_or_ref => return gz.addDecl(.decl_ref, decl_index, ident),
3734 else => return rvalue(gz, scope, rl, try gz.addDecl(.decl_val, decl_index, ident), ident),
3750 .ref, .none_or_ref => return gz.addStrTok(.decl_ref_named, str_index, ident_token),
3751 else => {
3752 const result = try gz.addStrTok(.decl_val_named, str_index, ident_token);
3753 return rvalue(gz, scope, rl, result, ident);
3754 },
37353755 }
37363756}
37373757
src/Compilation.zig+25-19
......@@ -531,7 +531,7 @@ pub const InitOptions = struct {
531531 /// is externally modified - essentially anything other than zig-cache - then
532532 /// this flag would be set to disable this machinery to avoid false positives.
533533 disable_lld_caching: bool = false,
534 object_format: ?std.builtin.ObjectFormat = null,
534 object_format: ?std.Target.ObjectFormat = null,
535535 optimize_mode: std.builtin.Mode = .Debug,
536536 keep_source_files_loaded: bool = false,
537537 clang_argv: []const []const u8 = &[0][]const u8{},
......@@ -1041,6 +1041,10 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
10411041
10421042 try std_pkg.add(gpa, "builtin", builtin_pkg);
10431043 try std_pkg.add(gpa, "root", root_pkg);
1044 try std_pkg.add(gpa, "std", std_pkg);
1045
1046 try builtin_pkg.add(gpa, "std", std_pkg);
1047 try builtin_pkg.add(gpa, "builtin", builtin_pkg);
10441048 }
10451049
10461050 // TODO when we implement serialization and deserialization of incremental
......@@ -2993,7 +2997,8 @@ fn wantBuildLibCFromSource(comp: Compilation) bool {
29932997 .Exe => true,
29942998 };
29952999 return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and
2996 comp.bin_file.options.libc_installation == null;
3000 comp.bin_file.options.libc_installation == null and
3001 comp.bin_file.options.object_format != .c;
29973002}
29983003
29993004fn wantBuildGLibCFromSource(comp: Compilation) bool {
......@@ -3017,6 +3022,7 @@ fn wantBuildLibUnwindFromSource(comp: *Compilation) bool {
30173022 };
30183023 return comp.bin_file.options.link_libc and is_exe_or_dyn_lib and
30193024 comp.bin_file.options.libc_installation == null and
3025 comp.bin_file.options.object_format != .c and
30203026 target_util.libcNeedsLibUnwind(comp.getTarget());
30213027}
30223028
......@@ -3068,26 +3074,21 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
30683074
30693075 @setEvalBranchQuota(4000);
30703076 try buffer.writer().print(
3071 \\usingnamespace @import("std").builtin;
3072 \\/// Deprecated
3073 \\pub const arch = Target.current.cpu.arch;
3074 \\/// Deprecated
3075 \\pub const endian = Target.current.cpu.arch.endian();
3076 \\
3077 \\const std = @import("std");
30773078 \\/// Zig version. When writing code that supports multiple versions of Zig, prefer
30783079 \\/// feature detection (i.e. with `@hasDecl` or `@hasField`) over version checks.
3079 \\pub const zig_version = try @import("std").SemanticVersion.parse("{s}");
3080 \\pub const zig_version = try std.SemanticVersion.parse("{s}");
30803081 \\pub const zig_is_stage2 = {};
30813082 \\
3082 \\pub const output_mode = OutputMode.{};
3083 \\pub const link_mode = LinkMode.{};
3083 \\pub const output_mode = std.builtin.OutputMode.{};
3084 \\pub const link_mode = std.builtin.LinkMode.{};
30843085 \\pub const is_test = {};
30853086 \\pub const single_threaded = {};
3086 \\pub const abi = Abi.{};
3087 \\pub const cpu: Cpu = Cpu{{
3087 \\pub const abi = std.Target.Abi.{};
3088 \\pub const cpu: std.Target.Cpu = .{{
30883089 \\ .arch = .{},
3089 \\ .model = &Target.{}.cpu.{},
3090 \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{
3090 \\ .model = &std.Target.{}.cpu.{},
3091 \\ .features = std.Target.{}.featureSet(&[_]std.Target.{}.Feature{{
30913092 \\
30923093 , .{
30933094 build_options.version,
......@@ -3115,7 +3116,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
31153116 try buffer.writer().print(
31163117 \\ }}),
31173118 \\}};
3118 \\pub const os = Os{{
3119 \\pub const os = std.Target.Os{{
31193120 \\ .tag = .{},
31203121 \\ .version_range = .{{
31213122 ,
......@@ -3202,8 +3203,13 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
32023203 (comp.bin_file.options.skip_linker_dependencies and comp.bin_file.options.parent_compilation_link_libc);
32033204
32043205 try buffer.writer().print(
3205 \\pub const object_format = ObjectFormat.{};
3206 \\pub const mode = Mode.{};
3206 \\pub const target = std.Target{{
3207 \\ .cpu = cpu,
3208 \\ .os = os,
3209 \\ .abi = abi,
3210 \\}};
3211 \\pub const object_format = std.Target.ObjectFormat.{};
3212 \\pub const mode = std.builtin.Mode.{};
32073213 \\pub const link_libc = {};
32083214 \\pub const link_libcpp = {};
32093215 \\pub const have_error_return_tracing = {};
......@@ -3211,7 +3217,7 @@ pub fn generateBuiltinZigSource(comp: *Compilation, allocator: *Allocator) Alloc
32113217 \\pub const position_independent_code = {};
32123218 \\pub const position_independent_executable = {};
32133219 \\pub const strip_debug_info = {};
3214 \\pub const code_model = CodeModel.{};
3220 \\pub const code_model = std.builtin.CodeModel.{};
32153221 \\
32163222 , .{
32173223 std.zig.fmtId(@tagName(comp.bin_file.options.object_format)),
src/Module.zig+130-10
......@@ -657,6 +657,7 @@ pub const Scope = struct {
657657 /// Direct children of the namespace. Used during an update to detect
658658 /// which decls have been added/removed from source.
659659 decls: std.AutoArrayHashMapUnmanaged(*Decl, void) = .{},
660 usingnamespace_set: std.AutoHashMapUnmanaged(*Namespace, bool) = .{},
660661
661662 pub fn deinit(ns: *Namespace, gpa: *Allocator) void {
662663 ns.decls.deinit(gpa);
......@@ -2540,6 +2541,7 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
25402541 .code = code,
25412542 .inst_map = try analysis_arena.allocator.alloc(*ir.Inst, code.instructions.len),
25422543 .owner_decl = decl,
2544 .namespace = decl.namespace,
25432545 .func = null,
25442546 .owner_func = null,
25452547 .param_inst_list = &.{},
......@@ -2560,7 +2562,73 @@ fn astgenAndSemaDecl(mod: *Module, decl: *Decl) !bool {
25602562 decl.generation = mod.generation;
25612563 return true;
25622564 },
2563 .@"usingnamespace" => @panic("TODO usingnamespace decl"),
2565 .@"usingnamespace" => {
2566 decl.analysis = .in_progress;
2567
2568 const type_expr = node_datas[decl_node].lhs;
2569 const is_pub = blk: {
2570 const main_tokens = tree.nodes.items(.main_token);
2571 const token_tags = tree.tokens.items(.tag);
2572 const main_token = main_tokens[decl_node];
2573 break :blk (main_token > 0 and token_tags[main_token - 1] == .keyword_pub);
2574 };
2575
2576 // A usingnamespace decl does not store any value so we can
2577 // deinit this arena after analysis is done.
2578 var analysis_arena = std.heap.ArenaAllocator.init(mod.gpa);
2579 defer analysis_arena.deinit();
2580
2581 var code: zir.Code = blk: {
2582 var astgen = try AstGen.init(mod, decl, &analysis_arena.allocator);
2583 defer astgen.deinit();
2584
2585 var gen_scope: Scope.GenZir = .{
2586 .force_comptime = true,
2587 .parent = &decl.namespace.base,
2588 .astgen = &astgen,
2589 };
2590 defer gen_scope.instructions.deinit(mod.gpa);
2591
2592 const ns_type = try AstGen.typeExpr(&gen_scope, &gen_scope.base, type_expr);
2593 _ = try gen_scope.addBreak(.break_inline, 0, ns_type);
2594
2595 const code = try gen_scope.finish();
2596 if (std.builtin.mode == .Debug and mod.comp.verbose_ir) {
2597 code.dump(mod.gpa, "usingnamespace_type", &gen_scope.base, 0) catch {};
2598 }
2599 break :blk code;
2600 };
2601 defer code.deinit(mod.gpa);
2602
2603 var sema: Sema = .{
2604 .mod = mod,
2605 .gpa = mod.gpa,
2606 .arena = &analysis_arena.allocator,
2607 .code = code,
2608 .inst_map = try analysis_arena.allocator.alloc(*ir.Inst, code.instructions.len),
2609 .owner_decl = decl,
2610 .namespace = decl.namespace,
2611 .func = null,
2612 .owner_func = null,
2613 .param_inst_list = &.{},
2614 };
2615 var block_scope: Scope.Block = .{
2616 .parent = null,
2617 .sema = &sema,
2618 .src_decl = decl,
2619 .instructions = .{},
2620 .inlining = null,
2621 .is_comptime = true,
2622 };
2623 defer block_scope.instructions.deinit(mod.gpa);
2624
2625 const ty = try sema.rootAsType(&block_scope);
2626 try decl.namespace.usingnamespace_set.put(mod.gpa, ty.getNamespace().?, is_pub);
2627
2628 decl.analysis = .complete;
2629 decl.generation = mod.generation;
2630 return true;
2631 },
25642632 else => unreachable,
25652633 }
25662634}
......@@ -2765,6 +2833,7 @@ fn astgenAndSemaFn(
27652833 .code = fn_type_code,
27662834 .inst_map = try fn_type_scope_arena.allocator.alloc(*ir.Inst, fn_type_code.instructions.len),
27672835 .owner_decl = decl,
2836 .namespace = decl.namespace,
27682837 .func = null,
27692838 .owner_func = null,
27702839 .param_inst_list = &.{},
......@@ -3064,6 +3133,7 @@ fn astgenAndSemaVarDecl(
30643133 .code = code,
30653134 .inst_map = try gen_scope_arena.allocator.alloc(*ir.Inst, code.instructions.len),
30663135 .owner_decl = decl,
3136 .namespace = decl.namespace,
30673137 .func = null,
30683138 .owner_func = null,
30693139 .param_inst_list = &.{},
......@@ -3125,6 +3195,7 @@ fn astgenAndSemaVarDecl(
31253195 .code = code,
31263196 .inst_map = try type_scope_arena.allocator.alloc(*ir.Inst, code.instructions.len),
31273197 .owner_decl = decl,
3198 .namespace = decl.namespace,
31283199 .func = null,
31293200 .owner_func = null,
31303201 .param_inst_list = &.{},
......@@ -3387,6 +3458,7 @@ pub fn importFile(mod: *Module, cur_pkg: *Package, import_string: []const u8) !*
33873458 .code = code,
33883459 .inst_map = try gen_scope_arena.allocator.alloc(*ir.Inst, code.instructions.len),
33893460 .owner_decl = top_decl,
3461 .namespace = top_decl.namespace,
33903462 .func = null,
33913463 .owner_func = null,
33923464 .param_inst_list = &.{},
......@@ -3411,7 +3483,7 @@ pub fn importFile(mod: *Module, cur_pkg: *Package, import_string: []const u8) !*
34113483 struct_decl.contents_hash = top_decl.contents_hash;
34123484 new_file.namespace = struct_ty.getNamespace().?;
34133485 new_file.namespace.parent = null;
3414 new_file.namespace.parent_name_hash = tmp_namespace.parent_name_hash;
3486 //new_file.namespace.parent_name_hash = tmp_namespace.parent_name_hash;
34153487
34163488 // Transfer the dependencies to `owner_decl`.
34173489 assert(top_decl.dependants.count() == 0);
......@@ -3422,24 +3494,31 @@ pub fn importFile(mod: *Module, cur_pkg: *Package, import_string: []const u8) !*
34223494 _ = try mod.declareDeclDependency(struct_decl, dep);
34233495 }
34243496
3425 try mod.analyzeFile(new_file);
34263497 return new_file;
34273498}
34283499
34293500pub fn analyzeFile(mod: *Module, file: *Scope.File) !void {
3430 return mod.analyzeNamespace(file.namespace);
3501 // We call `getAstTree` here so that `analyzeFile` has the error set that includes
3502 // file system operations, but `analyzeNamespace` does not.
3503 const tree = try mod.getAstTree(file.namespace.file_scope);
3504 const decls = tree.rootDecls();
3505 return mod.analyzeNamespace(file.namespace, decls);
34313506}
34323507
3433pub fn analyzeNamespace(mod: *Module, namespace: *Scope.Namespace) !void {
3508pub fn analyzeNamespace(
3509 mod: *Module,
3510 namespace: *Scope.Namespace,
3511 decls: []const ast.Node.Index,
3512) InnerError!void {
34343513 const tracy = trace(@src());
34353514 defer tracy.end();
34363515
34373516 // We may be analyzing it for the first time, or this may be
34383517 // an incremental update. This code handles both cases.
3439 const tree = try mod.getAstTree(namespace.file_scope);
3518 assert(namespace.file_scope.status == .loaded_success); // Caller must ensure tree loaded.
3519 const tree: *const ast.Tree = &namespace.file_scope.tree;
34403520 const node_tags = tree.nodes.items(.tag);
34413521 const node_datas = tree.nodes.items(.data);
3442 const decls = tree.rootDecls();
34433522
34443523 try mod.comp.work_queue.ensureUnusedCapacity(decls.len);
34453524 try namespace.decls.ensureCapacity(mod.gpa, decls.len);
......@@ -3612,7 +3691,20 @@ pub fn analyzeNamespace(mod: *Module, namespace: *Scope.Namespace) !void {
36123691 }
36133692 },
36143693 .@"usingnamespace" => {
3615 log.err("TODO: analyze usingnamespace decl", .{});
3694 const name_index = mod.getNextAnonNameIndex();
3695 const name = try std.fmt.allocPrint(mod.gpa, "__usingnamespace_{d}", .{name_index});
3696 defer mod.gpa.free(name);
3697
3698 const name_hash = namespace.fullyQualifiedNameHash(name);
3699 const contents_hash = std.zig.hashSrc(tree.getNodeSource(decl_node));
3700
3701 const new_decl = try mod.createNewDecl(namespace, name, decl_node, name_hash, contents_hash);
3702 namespace.decls.putAssumeCapacity(new_decl, {});
3703
3704 mod.ensureDeclAnalyzed(new_decl) catch |err| switch (err) {
3705 error.OutOfMemory => return error.OutOfMemory,
3706 error.AnalysisFail => continue,
3707 };
36163708 },
36173709 else => unreachable,
36183710 };
......@@ -3900,6 +3992,7 @@ pub fn analyzeFnBody(mod: *Module, decl: *Decl, func: *Fn) !void {
39003992 .code = func.zir,
39013993 .inst_map = try mod.gpa.alloc(*ir.Inst, func.zir.instructions.len),
39023994 .owner_decl = decl,
3995 .namespace = decl.namespace,
39033996 .func = func,
39043997 .owner_func = func,
39053998 .param_inst_list = param_inst_list,
......@@ -4001,6 +4094,10 @@ fn createNewDecl(
40014094 const new_decl = try mod.allocateNewDecl(namespace, src_node, contents_hash);
40024095 errdefer mod.gpa.destroy(new_decl);
40034096 new_decl.name = try mem.dupeZ(mod.gpa, u8, decl_name);
4097 log.debug("insert Decl {s} with hash {}", .{
4098 new_decl.name,
4099 std.fmt.fmtSliceHexLower(&name_hash),
4100 });
40044101 mod.decl_table.putAssumeCapacityNoClobber(name_hash, new_decl);
40054102 return new_decl;
40064103}
......@@ -4245,7 +4342,7 @@ fn getNextAnonNameIndex(mod: *Module) usize {
42454342pub fn lookupIdentifier(mod: *Module, scope: *Scope, ident_name: []const u8) ?*Decl {
42464343 var namespace = scope.namespace();
42474344 while (true) {
4248 if (mod.lookupInNamespace(namespace, ident_name)) |decl| {
4345 if (mod.lookupInNamespace(namespace, ident_name, false)) |decl| {
42494346 return decl;
42504347 }
42514348 namespace = namespace.parent orelse break;
......@@ -4259,9 +4356,32 @@ pub fn lookupInNamespace(
42594356 mod: *Module,
42604357 namespace: *Scope.Namespace,
42614358 ident_name: []const u8,
4359 only_pub_usingnamespaces: bool,
42624360) ?*Decl {
42634361 const name_hash = namespace.fullyQualifiedNameHash(ident_name);
4264 return mod.decl_table.get(name_hash);
4362 log.debug("lookup Decl {s} with hash {}", .{
4363 ident_name,
4364 std.fmt.fmtSliceHexLower(&name_hash),
4365 });
4366 // TODO handle decl collision with usingnamespace
4367 // TODO the decl doing the looking up needs to create a decl dependency
4368 // on each usingnamespace decl here.
4369 if (mod.decl_table.get(name_hash)) |decl| {
4370 return decl;
4371 }
4372 {
4373 var it = namespace.usingnamespace_set.iterator();
4374 while (it.next()) |entry| {
4375 const other_ns = entry.key;
4376 const other_is_pub = entry.value;
4377 if (only_pub_usingnamespaces and !other_is_pub) continue;
4378 // TODO handle cycles
4379 if (mod.lookupInNamespace(other_ns, ident_name, true)) |decl| {
4380 return decl;
4381 }
4382 }
4383 }
4384 return null;
42654385}
42664386
42674387pub fn makeIntType(arena: *Allocator, signedness: std.builtin.Signedness, bits: u16) !Type {
src/Sema.zig+186-66
......@@ -17,6 +17,8 @@ inst_map: []*Inst,
1717/// and `src_decl` of `Scope.Block` is the `Decl` of the callee.
1818/// This `Decl` owns the arena memory of this `Sema`.
1919owner_decl: *Decl,
20/// How to look up decl names.
21namespace: *Scope.Namespace,
2022/// For an inline or comptime function call, this will be the root parent function
2123/// which contains the callsite. Corresponds to `owner_decl`.
2224owner_func: ?*Module.Fn,
......@@ -169,7 +171,9 @@ pub fn analyzeBody(
169171 .cmp_neq => try sema.zirCmp(block, inst, .neq),
170172 .coerce_result_ptr => try sema.zirCoerceResultPtr(block, inst),
171173 .decl_ref => try sema.zirDeclRef(block, inst),
174 .decl_ref_named => try sema.zirDeclRefNamed(block, inst),
172175 .decl_val => try sema.zirDeclVal(block, inst),
176 .decl_val_named => try sema.zirDeclValNamed(block, inst),
173177 .load => try sema.zirLoad(block, inst),
174178 .div => try sema.zirArithmetic(block, inst),
175179 .elem_ptr => try sema.zirElemPtr(block, inst),
......@@ -535,68 +539,10 @@ fn zirStructDecl(
535539 const inst_data = sema.code.instructions.items(.data)[inst].pl_node;
536540 const src = inst_data.src();
537541 const extra = sema.code.extraData(zir.Inst.StructDecl, inst_data.payload_index);
542 const body = sema.code.extra[extra.end..][0..extra.data.body_len];
538543 const fields_len = extra.data.fields_len;
539 const bit_bags_count = std.math.divCeil(usize, fields_len, 16) catch unreachable;
540544
541545 var new_decl_arena = std.heap.ArenaAllocator.init(sema.gpa);
542 errdefer new_decl_arena.deinit();
543
544 var fields_map: std.StringArrayHashMapUnmanaged(Module.Struct.Field) = .{};
545 try fields_map.ensureCapacity(&new_decl_arena.allocator, fields_len);
546
547 {
548 var field_index: usize = extra.end + bit_bags_count;
549 var bit_bag_index: usize = extra.end;
550 var cur_bit_bag: u32 = undefined;
551 var field_i: u32 = 0;
552 while (field_i < fields_len) : (field_i += 1) {
553 if (field_i % 16 == 0) {
554 cur_bit_bag = sema.code.extra[bit_bag_index];
555 bit_bag_index += 1;
556 }
557 const has_align = @truncate(u1, cur_bit_bag) != 0;
558 cur_bit_bag >>= 1;
559 const has_default = @truncate(u1, cur_bit_bag) != 0;
560 cur_bit_bag >>= 1;
561
562 const field_name_zir = sema.code.nullTerminatedString(sema.code.extra[field_index]);
563 field_index += 1;
564 const field_type_ref = @intToEnum(zir.Inst.Ref, sema.code.extra[field_index]);
565 field_index += 1;
566
567 // This string needs to outlive the ZIR code.
568 const field_name = try new_decl_arena.allocator.dupe(u8, field_name_zir);
569 // TODO: if we need to report an error here, use a source location
570 // that points to this type expression rather than the struct.
571 // But only resolve the source location if we need to emit a compile error.
572 const field_ty = try sema.resolveType(block, src, field_type_ref);
573
574 const gop = fields_map.getOrPutAssumeCapacity(field_name);
575 assert(!gop.found_existing);
576 gop.entry.value = .{
577 .ty = field_ty,
578 .abi_align = Value.initTag(.abi_align_default),
579 .default_val = Value.initTag(.unreachable_value),
580 };
581
582 if (has_align) {
583 const align_ref = @intToEnum(zir.Inst.Ref, sema.code.extra[field_index]);
584 field_index += 1;
585 // TODO: if we need to report an error here, use a source location
586 // that points to this alignment expression rather than the struct.
587 // But only resolve the source location if we need to emit a compile error.
588 gop.entry.value.abi_align = (try sema.resolveInstConst(block, src, align_ref)).val;
589 }
590 if (has_default) {
591 const default_ref = @intToEnum(zir.Inst.Ref, sema.code.extra[field_index]);
592 field_index += 1;
593 // TODO: if we need to report an error here, use a source location
594 // that points to this default value expression rather than the struct.
595 // But only resolve the source location if we need to emit a compile error.
596 gop.entry.value.default_val = (try sema.resolveInstConst(block, src, default_ref)).val;
597 }
598 }
599 }
600546
601547 const struct_obj = try new_decl_arena.allocator.create(Module.Struct);
602548 const struct_ty = try Type.Tag.@"struct".create(&new_decl_arena.allocator, struct_obj);
......@@ -607,7 +553,7 @@ fn zirStructDecl(
607553 });
608554 struct_obj.* = .{
609555 .owner_decl = sema.owner_decl,
610 .fields = fields_map,
556 .fields = .{},
611557 .node_offset = inst_data.src_node,
612558 .namespace = .{
613559 .parent = sema.owner_decl.namespace,
......@@ -616,6 +562,128 @@ fn zirStructDecl(
616562 .file_scope = block.getFileScope(),
617563 },
618564 };
565
566 {
567 const ast = std.zig.ast;
568 const node = sema.owner_decl.relativeToNodeIndex(inst_data.src_node);
569 const tree: *const ast.Tree = &struct_obj.namespace.file_scope.tree;
570 const node_tags = tree.nodes.items(.tag);
571 var buf: [2]ast.Node.Index = undefined;
572 const members: []const ast.Node.Index = switch (node_tags[node]) {
573 .container_decl,
574 .container_decl_trailing,
575 => tree.containerDecl(node).ast.members,
576
577 .container_decl_two,
578 .container_decl_two_trailing,
579 => tree.containerDeclTwo(&buf, node).ast.members,
580
581 .container_decl_arg,
582 .container_decl_arg_trailing,
583 => tree.containerDeclArg(node).ast.members,
584
585 .root => tree.rootDecls(),
586 else => unreachable,
587 };
588 try sema.mod.analyzeNamespace(&struct_obj.namespace, members);
589 }
590
591 if (fields_len == 0) {
592 assert(body.len == 0);
593 return sema.analyzeDeclVal(block, src, new_decl);
594 }
595
596 try struct_obj.fields.ensureCapacity(&new_decl_arena.allocator, fields_len);
597
598 {
599 // We create a block for the field type instructions because they
600 // may need to reference Decls from inside the struct namespace.
601 // Within the field type, default value, and alignment expressions, the "owner decl"
602 // should be the struct itself. Thus we need a new Sema.
603 var struct_sema: Sema = .{
604 .mod = sema.mod,
605 .gpa = sema.mod.gpa,
606 .arena = &new_decl_arena.allocator,
607 .code = sema.code,
608 .inst_map = sema.inst_map,
609 .owner_decl = new_decl,
610 .namespace = &struct_obj.namespace,
611 .owner_func = null,
612 .func = null,
613 .param_inst_list = &.{},
614 .branch_quota = sema.branch_quota,
615 .branch_count = sema.branch_count,
616 };
617
618 var struct_block: Scope.Block = .{
619 .parent = null,
620 .sema = &struct_sema,
621 .src_decl = new_decl,
622 .instructions = .{},
623 .inlining = null,
624 .is_comptime = true,
625 };
626 defer assert(struct_block.instructions.items.len == 0); // should all be comptime instructions
627
628 _ = try struct_sema.analyzeBody(&struct_block, body);
629
630 sema.branch_count = struct_sema.branch_count;
631 sema.branch_quota = struct_sema.branch_quota;
632 }
633 const bit_bags_count = std.math.divCeil(usize, fields_len, 16) catch unreachable;
634 const body_end = extra.end + body.len;
635 var field_index: usize = body_end + bit_bags_count;
636 var bit_bag_index: usize = body_end;
637 var cur_bit_bag: u32 = undefined;
638 var field_i: u32 = 0;
639 while (field_i < fields_len) : (field_i += 1) {
640 if (field_i % 16 == 0) {
641 cur_bit_bag = sema.code.extra[bit_bag_index];
642 bit_bag_index += 1;
643 }
644 const has_align = @truncate(u1, cur_bit_bag) != 0;
645 cur_bit_bag >>= 1;
646 const has_default = @truncate(u1, cur_bit_bag) != 0;
647 cur_bit_bag >>= 1;
648
649 const field_name_zir = sema.code.nullTerminatedString(sema.code.extra[field_index]);
650 field_index += 1;
651 const field_type_ref = @intToEnum(zir.Inst.Ref, sema.code.extra[field_index]);
652 field_index += 1;
653
654 // This string needs to outlive the ZIR code.
655 const field_name = try new_decl_arena.allocator.dupe(u8, field_name_zir);
656 // TODO: if we need to report an error here, use a source location
657 // that points to this type expression rather than the struct.
658 // But only resolve the source location if we need to emit a compile error.
659 const field_ty = try sema.resolveType(block, src, field_type_ref);
660
661 const gop = struct_obj.fields.getOrPutAssumeCapacity(field_name);
662 assert(!gop.found_existing);
663 gop.entry.value = .{
664 .ty = field_ty,
665 .abi_align = Value.initTag(.abi_align_default),
666 .default_val = Value.initTag(.unreachable_value),
667 };
668
669 if (has_align) {
670 const align_ref = @intToEnum(zir.Inst.Ref, sema.code.extra[field_index]);
671 field_index += 1;
672 // TODO: if we need to report an error here, use a source location
673 // that points to this alignment expression rather than the struct.
674 // But only resolve the source location if we need to emit a compile error.
675 gop.entry.value.abi_align = (try sema.resolveInstConst(block, src, align_ref)).val;
676 }
677 if (has_default) {
678 const default_ref = @intToEnum(zir.Inst.Ref, sema.code.extra[field_index]);
679 field_index += 1;
680 // TODO: if we need to report an error here, use a source location
681 // that points to this default value expression rather than the struct.
682 // But only resolve the source location if we need to emit a compile error.
683 gop.entry.value.default_val = (try sema.resolveInstConst(block, src, default_ref)).val;
684 }
685 }
686
619687 return sema.analyzeDeclVal(block, src, new_decl);
620688}
621689
......@@ -1447,6 +1515,34 @@ fn zirDeclVal(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
14471515 return sema.analyzeDeclVal(block, src, decl);
14481516}
14491517
1518fn zirDeclRefNamed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1519 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
1520 const src = inst_data.src();
1521 const decl_name = inst_data.get(sema.code);
1522 const decl = try sema.lookupIdentifier(block, src, decl_name);
1523 return sema.analyzeDeclRef(block, src, decl);
1524}
1525
1526fn zirDeclValNamed(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!*Inst {
1527 const inst_data = sema.code.instructions.items(.data)[inst].str_tok;
1528 const src = inst_data.src();
1529 const decl_name = inst_data.get(sema.code);
1530 const decl = try sema.lookupIdentifier(block, src, decl_name);
1531 return sema.analyzeDeclVal(block, src, decl);
1532}
1533
1534fn lookupIdentifier(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, name: []const u8) !*Decl {
1535 const mod = sema.mod;
1536 const decl = mod.lookupIdentifier(&sema.namespace.base, name) orelse {
1537 // TODO insert a "dependency on the non-existence of a decl" here to make this
1538 // compile error go away when the decl is introduced. This data should be in a global
1539 // sparse map since it is only relevant when a compile error occurs.
1540 return mod.fail(&block.base, src, "use of undeclared identifier '{s}'", .{name});
1541 };
1542 _ = try mod.declareDeclDependency(sema.owner_decl, decl);
1543 return decl;
1544}
1545
14501546fn zirCallNone(
14511547 sema: *Sema,
14521548 block: *Scope.Block,
......@@ -1587,6 +1683,7 @@ fn analyzeCall(
15871683 .code = module_fn.zir,
15881684 .inst_map = try sema.gpa.alloc(*ir.Inst, module_fn.zir.instructions.len),
15891685 .owner_decl = sema.owner_decl,
1686 .namespace = sema.owner_decl.namespace,
15901687 .owner_func = sema.owner_func,
15911688 .func = module_fn,
15921689 .param_inst_list = casted_args,
......@@ -3647,7 +3744,7 @@ fn zirHasDecl(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError
36473744 "expected struct, enum, union, or opaque, found '{}'",
36483745 .{container_type},
36493746 );
3650 if (mod.lookupInNamespace(namespace, decl_name)) |decl| {
3747 if (mod.lookupInNamespace(namespace, decl_name, true)) |decl| {
36513748 if (decl.is_pub or decl.namespace.file_scope == block.base.namespace().file_scope) {
36523749 return mod.constBool(arena, src, true);
36533750 }
......@@ -3673,7 +3770,8 @@ fn zirImport(sema: *Sema, block: *Scope.Block, inst: zir.Inst.Index) InnerError!
36733770 return mod.fail(&block.base, src, "unable to find '{s}'", .{operand});
36743771 },
36753772 else => {
3676 // TODO: make sure this gets retried and not cached
3773 // TODO: these errors are file system errors; make sure an update() will
3774 // retry this and not cache the file system error, which may be transient.
36773775 return mod.fail(&block.base, src, "unable to open '{s}': {s}", .{ operand, @errorName(err) });
36783776 },
36793777 };
......@@ -4069,8 +4167,21 @@ fn zirCmp(
40694167
40704168 const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src);
40714169 const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src);
4072 try sema.requireRuntimeBlock(block, src); // TODO try to do it at comptime
4073 const bool_type = Type.initTag(.bool); // TODO handle vectors
4170
4171 if (casted_lhs.value()) |lhs_val| {
4172 if (casted_rhs.value()) |rhs_val| {
4173 if (lhs_val.isUndef() or rhs_val.isUndef()) {
4174 return sema.mod.constInst(sema.arena, src, .{
4175 .ty = resolved_type,
4176 .val = Value.initTag(.undef),
4177 });
4178 }
4179 const result = lhs_val.compare(op, rhs_val);
4180 return sema.mod.constBool(sema.arena, src, result);
4181 }
4182 }
4183
4184 try sema.requireRuntimeBlock(block, src);
40744185 const tag: Inst.Tag = switch (op) {
40754186 .lt => .cmp_lt,
40764187 .lte => .cmp_lte,
......@@ -4079,6 +4190,7 @@ fn zirCmp(
40794190 .gt => .cmp_gt,
40804191 .neq => .cmp_neq,
40814192 };
4193 const bool_type = Type.initTag(.bool); // TODO handle vectors
40824194 return block.addBinOp(src, bool_type, tag, casted_lhs, casted_rhs);
40834195}
40844196
......@@ -4525,7 +4637,7 @@ fn requireFunctionBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void
45254637
45264638fn requireRuntimeBlock(sema: *Sema, block: *Scope.Block, src: LazySrcLoc) !void {
45274639 if (block.is_comptime) {
4528 return sema.mod.fail(&block.base, src, "unable to resolve comptime value", .{});
4640 return sema.failWithNeededComptime(block, src);
45294641 }
45304642 try sema.requireFunctionBlock(block, src);
45314643}
......@@ -4775,7 +4887,7 @@ fn analyzeNamespaceLookup(
47754887) InnerError!?*Inst {
47764888 const mod = sema.mod;
47774889 const gpa = sema.gpa;
4778 if (mod.lookupInNamespace(namespace, decl_name)) |decl| {
4890 if (mod.lookupInNamespace(namespace, decl_name, true)) |decl| {
47794891 if (!decl.is_pub and decl.namespace.file_scope != block.getFileScope()) {
47804892 const msg = msg: {
47814893 const msg = try mod.errMsg(&block.base, src, "'{s}' is not marked 'pub'", .{
......@@ -5639,6 +5751,14 @@ fn resolvePeerTypes(sema: *Sema, block: *Scope.Block, src: LazySrcLoc, instructi
56395751 continue;
56405752 }
56415753
5754 if (chosen.ty.zigTypeTag() == .Enum and candidate.ty.zigTypeTag() == .EnumLiteral) {
5755 continue;
5756 }
5757 if (chosen.ty.zigTypeTag() == .EnumLiteral and candidate.ty.zigTypeTag() == .Enum) {
5758 chosen = candidate;
5759 continue;
5760 }
5761
56425762 // TODO error notes pointing out each type
56435763 return sema.mod.fail(&block.base, src, "incompatible types: '{}' and '{}'", .{ chosen.ty, candidate.ty });
56445764 }
src/codegen/spirv/spec.zig+1-1
......@@ -21,7 +21,7 @@
2121// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2222// FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
2323// IN THE MATERIALS.
24const Version = @import("builtin").Version;
24const Version = @import("std").builtin.Version;
2525pub const version = Version{ .major = 1, .minor = 5, .patch = 4 };
2626pub const magic_number: u32 = 0x07230203;
2727pub const Opcode = extern enum(u16) {
src/link.zig+1-1
......@@ -30,7 +30,7 @@ pub const Options = struct {
3030 target: std.Target,
3131 output_mode: std.builtin.OutputMode,
3232 link_mode: std.builtin.LinkMode,
33 object_format: std.builtin.ObjectFormat,
33 object_format: std.Target.ObjectFormat,
3434 optimize_mode: std.builtin.Mode,
3535 machine_code_model: std.builtin.CodeModel,
3636 root_name: []const u8,
src/stage1/codegen.cpp+24-18
......@@ -8921,10 +8921,10 @@ static const char *bool_to_str(bool b) {
89218921
89228922static const char *build_mode_to_str(BuildMode build_mode) {
89238923 switch (build_mode) {
8924 case BuildModeDebug: return "Mode.Debug";
8925 case BuildModeSafeRelease: return "Mode.ReleaseSafe";
8926 case BuildModeFastRelease: return "Mode.ReleaseFast";
8927 case BuildModeSmallRelease: return "Mode.ReleaseSmall";
8924 case BuildModeDebug: return "Debug";
8925 case BuildModeSafeRelease: return "ReleaseSafe";
8926 case BuildModeFastRelease: return "ReleaseFast";
8927 case BuildModeSmallRelease: return "ReleaseSmall";
89288928 }
89298929 zig_unreachable();
89308930}
......@@ -8995,7 +8995,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
89958995 g->have_err_ret_tracing = detect_err_ret_tracing(g);
89968996
89978997 Buf *contents = buf_alloc();
8998 buf_appendf(contents, "usingnamespace @import(\"std\").builtin;\n\n");
8998 buf_appendf(contents,
8999 "const std = @import(\"std\");\n"
9000 );
89999001
90009002 const char *cur_os = nullptr;
90019003 {
......@@ -9089,19 +9091,23 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
90899091 static_assert(TargetSubsystemEfiRom == 6, "");
90909092 static_assert(TargetSubsystemEfiRuntimeDriver == 7, "");
90919093
9092 buf_append_str(contents, "/// Deprecated: use `std.Target.current.cpu.arch`\n");
9093 buf_append_str(contents, "pub const arch = Target.current.cpu.arch;\n");
9094 buf_append_str(contents, "/// Deprecated: use `std.Target.current.cpu.arch.endian()`\n");
9095 buf_append_str(contents, "pub const endian = Target.current.cpu.arch.endian();\n");
9096 buf_appendf(contents, "pub const output_mode = OutputMode.Obj;\n");
9097 buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", ZIG_QUOTE(ZIG_LINK_MODE));
9094 buf_appendf(contents, "pub const output_mode = std.builtin.OutputMode.Obj;\n");
9095 buf_appendf(contents, "pub const link_mode = std.builtin.LinkMode.%s;\n", ZIG_QUOTE(ZIG_LINK_MODE));
90989096 buf_appendf(contents, "pub const is_test = false;\n");
90999097 buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));
9100 buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi);
9101 buf_appendf(contents, "pub const cpu: Cpu = Target.Cpu.baseline(.%s);\n", cur_arch);
9102 buf_appendf(contents, "pub const os = Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os);
9103 buf_appendf(contents, "pub const object_format = ObjectFormat.%s;\n", cur_obj_fmt);
9104 buf_appendf(contents, "pub const mode = %s;\n", build_mode_to_str(g->build_mode));
9098 buf_appendf(contents, "pub const abi = std.Target.Abi.%s;\n", cur_abi);
9099 buf_appendf(contents, "pub const cpu = std.Target.Cpu.baseline(.%s);\n", cur_arch);
9100 buf_appendf(contents, "pub const os = std.Target.Os.Tag.defaultVersionRange(.%s);\n", cur_os);
9101 buf_appendf(contents,
9102 "pub const target = std.Target{\n"
9103 " .cpu = cpu,\n"
9104 " .os = os,\n"
9105 " .abi = abi,\n"
9106 "};\n"
9107 );
9108
9109 buf_appendf(contents, "pub const object_format = std.Target.ObjectFormat.%s;\n", cur_obj_fmt);
9110 buf_appendf(contents, "pub const mode = std.builtin.Mode.%s;\n", build_mode_to_str(g->build_mode));
91059111 buf_appendf(contents, "pub const link_libc = %s;\n", bool_to_str(g->link_libc));
91069112 buf_appendf(contents, "pub const link_libcpp = %s;\n", bool_to_str(g->link_libcpp));
91079113 buf_appendf(contents, "pub const have_error_return_tracing = %s;\n", bool_to_str(g->have_err_ret_tracing));
......@@ -9109,13 +9115,13 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
91099115 buf_appendf(contents, "pub const position_independent_code = %s;\n", bool_to_str(g->have_pic));
91109116 buf_appendf(contents, "pub const position_independent_executable = %s;\n", bool_to_str(g->have_pie));
91119117 buf_appendf(contents, "pub const strip_debug_info = %s;\n", bool_to_str(g->strip_debug_symbols));
9112 buf_appendf(contents, "pub const code_model = CodeModel.default;\n");
9118 buf_appendf(contents, "pub const code_model = std.builtin.CodeModel.default;\n");
91139119 buf_appendf(contents, "pub const zig_is_stage2 = false;\n");
91149120
91159121 {
91169122 TargetSubsystem detected_subsystem = detect_subsystem(g);
91179123 if (detected_subsystem != TargetSubsystemAuto) {
9118 buf_appendf(contents, "pub const explicit_subsystem = SubSystem.%s;\n", subsystem_to_str(detected_subsystem));
9124 buf_appendf(contents, "pub const explicit_subsystem = std.builtin.SubSystem.%s;\n", subsystem_to_str(detected_subsystem));
91199125 }
91209126 }
91219127
src/value.zig+19-8
......@@ -930,7 +930,11 @@ pub const Value = extern union {
930930
931931 /// Asserts the value is comparable.
932932 pub fn compare(lhs: Value, op: std.math.CompareOperator, rhs: Value) bool {
933 return order(lhs, rhs).compare(op);
933 return switch (op) {
934 .eq => lhs.eql(rhs),
935 .neq => !lhs.eql(rhs),
936 else => order(lhs, rhs).compare(op),
937 };
934938 }
935939
936940 /// Asserts the value is comparable.
......@@ -942,12 +946,19 @@ pub const Value = extern union {
942946 const a_tag = a.tag();
943947 const b_tag = b.tag();
944948 if (a_tag == b_tag) {
945 if (a_tag == .void_value or a_tag == .null_value) {
946 return true;
947 } else if (a_tag == .enum_literal) {
948 const a_name = a.castTag(.enum_literal).?.data;
949 const b_name = b.castTag(.enum_literal).?.data;
950 return std.mem.eql(u8, a_name, b_name);
949 switch (a_tag) {
950 .void_value, .null_value => return true,
951 .enum_literal => {
952 const a_name = a.castTag(.enum_literal).?.data;
953 const b_name = b.castTag(.enum_literal).?.data;
954 return std.mem.eql(u8, a_name, b_name);
955 },
956 .enum_field_index => {
957 const a_field_index = a.castTag(.enum_field_index).?.data;
958 const b_field_index = b.castTag(.enum_field_index).?.data;
959 return a_field_index == b_field_index;
960 },
961 else => {},
951962 }
952963 }
953964 if (a.isType() and b.isType()) {
......@@ -958,7 +969,7 @@ pub const Value = extern union {
958969 const b_type = b.toType(&fib.allocator) catch unreachable;
959970 return a_type.eql(b_type);
960971 }
961 return compare(a, .eq, b);
972 return order(a, b).compare(.eq);
962973 }
963974
964975 pub fn hash_u32(self: Value) u32 {
src/zir.zig+40-6
......@@ -294,6 +294,12 @@ pub const Inst = struct {
294294 /// Equivalent to a decl_ref followed by load.
295295 /// Uses the `pl_node` union field. `payload_index` is into `decls`.
296296 decl_val,
297 /// Same as `decl_ref` except instead of indexing into decls, uses
298 /// a name to identify the Decl. Uses the `str_tok` union field.
299 decl_ref_named,
300 /// Same as `decl_val` except instead of indexing into decls, uses
301 /// a name to identify the Decl. Uses the `str_tok` union field.
302 decl_val_named,
297303 /// Load the value from a pointer. Assumes `x.*` syntax.
298304 /// Uses `un_node` field. AST node is the `x.*` syntax.
299305 load,
......@@ -744,6 +750,8 @@ pub const Inst = struct {
744750 .dbg_stmt_node,
745751 .decl_ref,
746752 .decl_val,
753 .decl_ref_named,
754 .decl_val_named,
747755 .load,
748756 .div,
749757 .elem_ptr,
......@@ -1507,17 +1515,19 @@ pub const Inst = struct {
15071515 };
15081516
15091517 /// Trailing:
1510 /// 0. has_bits: u32 // for every 16 fields
1518 /// 0. inst: Index // for every body_len
1519 /// 1. has_bits: u32 // for every 16 fields
15111520 /// - sets of 2 bits:
15121521 /// 0b0X: whether corresponding field has an align expression
15131522 /// 0bX0: whether corresponding field has a default expression
1514 /// 1. fields: { // for every fields_len
1523 /// 2. fields: { // for every fields_len
15151524 /// field_name: u32,
15161525 /// field_type: Ref,
15171526 /// align: Ref, // if corresponding bit is set
15181527 /// default_value: Ref, // if corresponding bit is set
15191528 /// }
15201529 pub const StructDecl = struct {
1530 body_len: u32,
15211531 fields_len: u32,
15221532 };
15231533
......@@ -1792,6 +1802,8 @@ const Writer = struct {
17921802
17931803 .error_value,
17941804 .enum_literal,
1805 .decl_ref_named,
1806 .decl_val_named,
17951807 => try self.writeStrTok(stream, inst),
17961808
17971809 .fn_type => try self.writeFnType(stream, inst, false),
......@@ -1872,7 +1884,16 @@ const Writer = struct {
18721884 inst: Inst.Index,
18731885 ) (@TypeOf(stream).Error || error{OutOfMemory})!void {
18741886 const inst_data = self.code.instructions.items(.data)[inst].ptr_type_simple;
1875 try stream.writeAll("TODO)");
1887 const str_allowzero = if (inst_data.is_allowzero) "allowzero, " else "";
1888 const str_const = if (!inst_data.is_mutable) "const, " else "";
1889 const str_volatile = if (inst_data.is_volatile) "volatile, " else "";
1890 try self.writeInstRef(stream, inst_data.elem_type);
1891 try stream.print(", {s}{s}{s}{s})", .{
1892 str_allowzero,
1893 str_const,
1894 str_volatile,
1895 @tagName(inst_data.size),
1896 });
18761897 }
18771898
18781899 fn writePtrType(
......@@ -1991,14 +2012,27 @@ const Writer = struct {
19912012 fn writeStructDecl(self: *Writer, stream: anytype, inst: Inst.Index) !void {
19922013 const inst_data = self.code.instructions.items(.data)[inst].pl_node;
19932014 const extra = self.code.extraData(Inst.StructDecl, inst_data.payload_index);
2015 const body = self.code.extra[extra.end..][0..extra.data.body_len];
19942016 const fields_len = extra.data.fields_len;
1995 const bit_bags_count = std.math.divCeil(usize, fields_len, 16) catch unreachable;
2017
2018 if (fields_len == 0) {
2019 assert(body.len == 0);
2020 try stream.writeAll("{}, {}) ");
2021 try self.writeSrc(stream, inst_data.src());
2022 return;
2023 }
19962024
19972025 try stream.writeAll("{\n");
19982026 self.indent += 2;
2027 try self.writeBody(stream, body);
19992028
2000 var field_index: usize = extra.end + bit_bags_count;
2001 var bit_bag_index: usize = extra.end;
2029 try stream.writeByteNTimes(' ', self.indent - 2);
2030 try stream.writeAll("}, {\n");
2031
2032 const bit_bags_count = std.math.divCeil(usize, fields_len, 16) catch unreachable;
2033 const body_end = extra.end + body.len;
2034 var field_index: usize = body_end + bit_bags_count;
2035 var bit_bag_index: usize = body_end;
20022036 var cur_bit_bag: u32 = undefined;
20032037 var field_i: u32 = 0;
20042038 while (field_i < fields_len) : (field_i += 1) {
test/tests.zig+1-1
......@@ -507,7 +507,7 @@ pub fn addPkgTests(
507507 if (skip_single_threaded and test_target.single_threaded)
508508 continue;
509509
510 const ArchTag = std.meta.Tag(builtin.Arch);
510 const ArchTag = std.meta.Tag(std.Target.Cpu.Arch);
511511 if (test_target.disable_native and
512512 test_target.target.getOsTag() == std.Target.current.os.tag and
513513 test_target.target.getCpuArch() == std.Target.current.cpu.arch)