aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2021-02-18 20:09:29 -0700
committerAndrew Kelley <andrew@ziglang.org>2021-02-18 20:09:29 -0700
commit9010bd8aec612d5a14e4be800c80b72025fac2c5 (patch)
treec286b41d6b9d3131539586d75a22b91301a1d23d
parent29daf10639149bd023db0be4e04eaf154dce0f83 (diff)
downloadzig-9010bd8aec612d5a14e4be800c80b72025fac2c5.tar.gz
zig-9010bd8aec612d5a14e4be800c80b72025fac2c5.zip
stage2: astgen: fix most of the remaining compile errors
more progress on converting astgen to the new AST memory layout. only a few code paths left to update.
-rw-r--r--lib/std/zig/ast.zig40
-rw-r--r--lib/std/zig/render.zig48
-rw-r--r--src/BuiltinFn.zig1043
-rw-r--r--src/Module.zig17
-rw-r--r--src/astgen.zig699
-rw-r--r--src/zir.zig16
-rw-r--r--src/zir_sema.zig12
7 files changed, 1052 insertions, 823 deletions
diff --git a/lib/std/zig/ast.zig b/lib/std/zig/ast.zig
index 72b47ecd3f..c8f9afd080 100644
--- a/lib/std/zig/ast.zig
+++ b/lib/std/zig/ast.zig
@@ -1754,25 +1754,20 @@ pub const Tree = struct {
const token_tags = tree.tokens.items(.tag);
// TODO: looks like stage1 isn't quite smart enough to handle enum
// literals in some places here
- const Kind = full.PtrType.Kind;
- const kind: Kind = switch (token_tags[info.main_token]) {
+ const Size = std.builtin.TypeInfo.Pointer.Size;
+ const size: Size = switch (token_tags[info.main_token]) {
.asterisk,
.asterisk_asterisk,
=> switch (token_tags[info.main_token + 1]) {
- .r_bracket => .many,
- .colon => .sentinel,
- .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Kind.c else .one,
- else => .one,
- },
- .l_bracket => switch (token_tags[info.main_token + 1]) {
- .r_bracket => Kind.slice,
- .colon => .slice_sentinel,
- else => unreachable,
+ .r_bracket, .colon => .Many,
+ .identifier => if (token_tags[info.main_token - 1] == .l_bracket) Size.C else .One,
+ else => .One,
},
+ .l_bracket => Size.Slice,
else => unreachable,
};
var result: full.PtrType = .{
- .kind = kind,
+ .size = size,
.allowzero_token = null,
.const_token = null,
.volatile_token = null,
@@ -1782,13 +1777,7 @@ pub const Tree = struct {
// here while looking for modifiers as that could result in false
// positives. Therefore, start after a sentinel if there is one and
// skip over any align node and bit range nodes.
- var i = if (kind == .sentinel or kind == .slice_sentinel) blk: {
- assert(info.sentinel != 0);
- break :blk tree.lastToken(info.sentinel) + 1;
- } else blk: {
- assert(info.sentinel == 0);
- break :blk info.main_token;
- };
+ var i = if (info.sentinel != 0) tree.lastToken(info.sentinel) + 1 else info.main_token;
const end = tree.firstToken(info.child_type);
while (i < end) : (i += 1) {
switch (token_tags[i]) {
@@ -2115,7 +2104,7 @@ pub const full = struct {
.comptime_noalias = comptime_noalias,
.name_token = name_token,
.anytype_ellipsis3 = it.tok_i - 1,
- .type_expr = param_type,
+ .type_expr = 0,
};
}
it.tok_flag = false;
@@ -2166,21 +2155,12 @@ pub const full = struct {
};
pub const PtrType = struct {
- kind: Kind,
+ size: std.builtin.TypeInfo.Pointer.Size,
allowzero_token: ?TokenIndex,
const_token: ?TokenIndex,
volatile_token: ?TokenIndex,
ast: Ast,
- pub const Kind = enum {
- one,
- many,
- sentinel,
- c,
- slice,
- slice_sentinel,
- };
-
pub const Ast = struct {
main_token: TokenIndex,
align_node: Node.Index,
diff --git a/lib/std/zig/render.zig b/lib/std/zig/render.zig
index f7608fe61a..c169a48b01 100644
--- a/lib/std/zig/render.zig
+++ b/lib/std/zig/render.zig
@@ -677,8 +677,8 @@ fn renderPtrType(
ptr_type: ast.full.PtrType,
space: Space,
) Error!void {
- switch (ptr_type.kind) {
- .one => {
+ switch (ptr_type.size) {
+ .One => {
// Since ** tokens exist and the same token is shared by two
// nested pointer types, we check to see if we are the parent
// in such a relationship. If so, skip rendering anything for
@@ -691,33 +691,35 @@ fn renderPtrType(
}
try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
},
- .many => {
- try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
- try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
- try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket
- },
- .sentinel => {
- try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
- try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
- try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
- try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
- try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
+ .Many => {
+ if (ptr_type.ast.sentinel == 0) {
+ try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
+ try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
+ try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket
+ } else {
+ try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
+ try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
+ try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
+ try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
+ try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
+ }
},
- .c => {
+ .C => {
try renderToken(ais, tree, ptr_type.ast.main_token - 1, .none); // lbracket
try renderToken(ais, tree, ptr_type.ast.main_token, .none); // asterisk
try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // c
try renderToken(ais, tree, ptr_type.ast.main_token + 2, .none); // rbracket
},
- .slice => {
- try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket
- try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket
- },
- .slice_sentinel => {
- try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket
- try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
- try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
- try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
+ .Slice => {
+ if (ptr_type.ast.sentinel == 0) {
+ try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket
+ try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // rbracket
+ } else {
+ try renderToken(ais, tree, ptr_type.ast.main_token, .none); // lbracket
+ try renderToken(ais, tree, ptr_type.ast.main_token + 1, .none); // colon
+ try renderExpression(ais, tree, ptr_type.ast.sentinel, .none);
+ try renderToken(ais, tree, tree.lastToken(ptr_type.ast.sentinel) + 1, .none); // rbracket
+ }
},
}
diff --git a/src/BuiltinFn.zig b/src/BuiltinFn.zig
index 9776edfef3..deb1cbfa76 100644
--- a/src/BuiltinFn.zig
+++ b/src/BuiltinFn.zig
@@ -115,727 +115,730 @@ allows_lvalue: bool = false,
/// of parameters.
param_count: ?u8,
-pub const list = std.ComptimeStringMap(@This(), .{
- .{
- "@addWithOverflow",
+pub const list = list: {
+ @setEvalBranchQuota(3000);
+ break :list std.ComptimeStringMap(@This(), .{
.{
- .tag = .add_with_overflow,
- .param_count = 4,
+ "@addWithOverflow",
+ .{
+ .tag = .add_with_overflow,
+ .param_count = 4,
+ },
},
- },
- .{
- "@alignCast",
.{
- .tag = align_cast,
- .param_count = 1,
+ "@alignCast",
+ .{
+ .tag = .align_cast,
+ .param_count = 1,
+ },
},
- },
- .{
- "@alignOf",
.{
- .tag = .align_of,
- .param_count = 1,
+ "@alignOf",
+ .{
+ .tag = .align_of,
+ .param_count = 1,
+ },
},
- },
- .{
- "@as",
.{
- .tag = .as,
- .needs_mem_loc = true,
- .param_count = 2,
+ "@as",
+ .{
+ .tag = .as,
+ .needs_mem_loc = true,
+ .param_count = 2,
+ },
},
- },
- .{
- "@asyncCall",
.{
- .tag = .async_call,
- .param_count = null,
+ "@asyncCall",
+ .{
+ .tag = .async_call,
+ .param_count = null,
+ },
},
- },
- .{
- "@atomicLoad",
.{
- .tag = .atomic_load,
- .param_count = 3,
+ "@atomicLoad",
+ .{
+ .tag = .atomic_load,
+ .param_count = 3,
+ },
},
- },
- .{
- "@atomicRmw",
.{
- .tag = .atomic_rmw,
- .param_count = 5,
+ "@atomicRmw",
+ .{
+ .tag = .atomic_rmw,
+ .param_count = 5,
+ },
},
- },
- .{
- "@atomicStore",
.{
- .tag = .atomic_store,
- .param_count = 4,
+ "@atomicStore",
+ .{
+ .tag = .atomic_store,
+ .param_count = 4,
+ },
},
- },
- .{
- "@bitCast",
.{
- .tag = .bit_cast,
- .needs_mem_loc = true,
- .param_count = 2,
+ "@bitCast",
+ .{
+ .tag = .bit_cast,
+ .needs_mem_loc = true,
+ .param_count = 2,
+ },
},
- },
- .{
- "@bitOffsetOf",
.{
- .tag = .bit_offset_of,
- .param_count = 2,
+ "@bitOffsetOf",
+ .{
+ .tag = .bit_offset_of,
+ .param_count = 2,
+ },
},
- },
- .{
- "@boolToInt",
.{
- .tag = .bool_to_int,
- .param_count = 1,
+ "@boolToInt",
+ .{
+ .tag = .bool_to_int,
+ .param_count = 1,
+ },
},
- },
- .{
- "@bitSizeOf",
.{
- .tag = .bit_size_of,
- .param_count = 1,
+ "@bitSizeOf",
+ .{
+ .tag = .bit_size_of,
+ .param_count = 1,
+ },
},
- },
- .{
- "@breakpoint",
.{
- .tag = .breakpoint,
- .param_count = 0,
+ "@breakpoint",
+ .{
+ .tag = .breakpoint,
+ .param_count = 0,
+ },
},
- },
- .{
- "@mulAdd",
.{
- .tag = .mul_add,
- .param_count = 4,
+ "@mulAdd",
+ .{
+ .tag = .mul_add,
+ .param_count = 4,
+ },
},
- },
- .{
- "@byteSwap",
.{
- .tag = .byte_swap,
- .param_count = 2,
+ "@byteSwap",
+ .{
+ .tag = .byte_swap,
+ .param_count = 2,
+ },
},
- },
- .{
- "@bitReverse",
.{
- .tag = .bit_reverse,
- .param_count = 2,
+ "@bitReverse",
+ .{
+ .tag = .bit_reverse,
+ .param_count = 2,
+ },
},
- },
- .{
- "@byteOffsetOf",
.{
- .tag = .byte_offset_of,
- .param_count = 2,
+ "@byteOffsetOf",
+ .{
+ .tag = .byte_offset_of,
+ .param_count = 2,
+ },
},
- },
- .{
- "@call",
.{
- .tag = .call,
- .needs_mem_loc = true,
- .param_count = 3,
+ "@call",
+ .{
+ .tag = .call,
+ .needs_mem_loc = true,
+ .param_count = 3,
+ },
},
- },
- .{
- "@cDefine",
.{
- .tag = .c_define,
- .param_count = 2,
+ "@cDefine",
+ .{
+ .tag = .c_define,
+ .param_count = 2,
+ },
},
- },
- .{
- "@cImport",
.{
- .tag = .c_import,
- .param_count = 1,
+ "@cImport",
+ .{
+ .tag = .c_import,
+ .param_count = 1,
+ },
},
- },
- .{
- "@cInclude",
.{
- .tag = .c_include,
- .param_count = 1,
+ "@cInclude",
+ .{
+ .tag = .c_include,
+ .param_count = 1,
+ },
},
- },
- .{
- "@clz",
.{
- .tag = .clz,
- .param_count = 2,
+ "@clz",
+ .{
+ .tag = .clz,
+ .param_count = 2,
+ },
},
- },
- .{
- "@cmpxchgStrong",
.{
- .tag = .cmpxchg_strong,
- .param_count = 6,
+ "@cmpxchgStrong",
+ .{
+ .tag = .cmpxchg_strong,
+ .param_count = 6,
+ },
},
- },
- .{
- "@cmpxchgWeak",
.{
- .tag = .cmpxchg_weak,
- .param_count = 6,
+ "@cmpxchgWeak",
+ .{
+ .tag = .cmpxchg_weak,
+ .param_count = 6,
+ },
},
- },
- .{
- "@compileError",
.{
- .tag = .compile_error,
- .param_count = 1,
+ "@compileError",
+ .{
+ .tag = .compile_error,
+ .param_count = 1,
+ },
},
- },
- .{
- "@compileLog",
.{
- .tag = .compile_log,
- .param_count = null,
+ "@compileLog",
+ .{
+ .tag = .compile_log,
+ .param_count = null,
+ },
},
- },
- .{
- "@ctz",
.{
- .tag = .ctz,
- .param_count = 2,
+ "@ctz",
+ .{
+ .tag = .ctz,
+ .param_count = 2,
+ },
},
- },
- .{
- "@cUndef",
.{
- .tag = .c_undef,
- .param_count = 1,
+ "@cUndef",
+ .{
+ .tag = .c_undef,
+ .param_count = 1,
+ },
},
- },
- .{
- "@divExact",
.{
- .tag = .div_exact,
- .param_count = 2,
+ "@divExact",
+ .{
+ .tag = .div_exact,
+ .param_count = 2,
+ },
},
- },
- .{
- "@divFloor",
.{
- .tag = .div_floor,
- .param_count = 2,
+ "@divFloor",
+ .{
+ .tag = .div_floor,
+ .param_count = 2,
+ },
},
- },
- .{
- "@divTrunc",
.{
- .tag = .div_trunc,
- .param_count = 2,
+ "@divTrunc",
+ .{
+ .tag = .div_trunc,
+ .param_count = 2,
+ },
},
- },
- .{
- "@embedFile",
.{
- .tag = .embed_file,
- .param_count = 1,
+ "@embedFile",
+ .{
+ .tag = .embed_file,
+ .param_count = 1,
+ },
},
- },
- .{
- "@enumToInt",
.{
- .tag = .enum_to_int,
- .param_count = 1,
+ "@enumToInt",
+ .{
+ .tag = .enum_to_int,
+ .param_count = 1,
+ },
},
- },
- .{
- "@errorName",
.{
- .tag = .error_name,
- .param_count = 1,
+ "@errorName",
+ .{
+ .tag = .error_name,
+ .param_count = 1,
+ },
},
- },
- .{
- "@errorReturnTrace",
.{
- .tag = .error_return_trace,
- .param_count = 0,
+ "@errorReturnTrace",
+ .{
+ .tag = .error_return_trace,
+ .param_count = 0,
+ },
},
- },
- .{
- "@errorToInt",
.{
- .tag = .error_to_int,
- .param_count = 1,
+ "@errorToInt",
+ .{
+ .tag = .error_to_int,
+ .param_count = 1,
+ },
},
- },
- .{
- "@errSetCast",
.{
- .tag = .err_set_cast,
- .param_count = 2,
+ "@errSetCast",
+ .{
+ .tag = .err_set_cast,
+ .param_count = 2,
+ },
},
- },
- .{
- "@export",
.{
- .tag = .@"export",
- .param_count = 2,
+ "@export",
+ .{
+ .tag = .@"export",
+ .param_count = 2,
+ },
},
- },
- .{
- "@fence",
.{
- .tag = .fence,
- .param_count = 0,
+ "@fence",
+ .{
+ .tag = .fence,
+ .param_count = 0,
+ },
},
- },
- .{
- "@field",
.{
- .tag = .field,
- .needs_mem_loc = true,
- .param_count = 2,
- .allows_lvalue = true,
+ "@field",
+ .{
+ .tag = .field,
+ .needs_mem_loc = true,
+ .param_count = 2,
+ .allows_lvalue = true,
+ },
},
- },
- .{
- "@fieldParentPtr",
.{
- .tag = .field_parent_ptr,
- .param_count = 3,
+ "@fieldParentPtr",
+ .{
+ .tag = .field_parent_ptr,
+ .param_count = 3,
+ },
},
- },
- .{
- "@floatCast",
.{
- .tag = .float_cast,
- .param_count = 1,
+ "@floatCast",
+ .{
+ .tag = .float_cast,
+ .param_count = 1,
+ },
},
- },
- .{
- "@floatToInt",
.{
- .tag = .float_to_int,
- .param_count = 1,
+ "@floatToInt",
+ .{
+ .tag = .float_to_int,
+ .param_count = 1,
+ },
},
- },
- .{
- "@frame",
.{
- .tag = .frame,
- .param_count = 0,
+ "@frame",
+ .{
+ .tag = .frame,
+ .param_count = 0,
+ },
},
- },
- .{
- "@Frame",
.{
- .tag = .Frame,
- .param_count = 1,
+ "@Frame",
+ .{
+ .tag = .Frame,
+ .param_count = 1,
+ },
},
- },
- .{
- "@frameAddress",
.{
- .tag = .frame_address,
- .param_count = 0,
+ "@frameAddress",
+ .{
+ .tag = .frame_address,
+ .param_count = 0,
+ },
},
- },
- .{
- "@frameSize",
.{
- .tag = .frame_size,
- .param_count = 1,
+ "@frameSize",
+ .{
+ .tag = .frame_size,
+ .param_count = 1,
+ },
},
- },
- .{
- "@hasDecl",
.{
- .tag = .has_decl,
- .param_count = 2,
+ "@hasDecl",
+ .{
+ .tag = .has_decl,
+ .param_count = 2,
+ },
},
- },
- .{
- "@hasField",
.{
- .tag = .has_field,
- .param_count = 2,
+ "@hasField",
+ .{
+ .tag = .has_field,
+ .param_count = 2,
+ },
},
- },
- .{
- "@import",
.{
- .tag = .import,
- .param_count = 1,
+ "@import",
+ .{
+ .tag = .import,
+ .param_count = 1,
+ },
},
- },
- .{
- "@intCast",
.{
- .tag = .int_cast,
- .param_count = 1,
+ "@intCast",
+ .{
+ .tag = .int_cast,
+ .param_count = 1,
+ },
},
- },
- .{
- "@intToEnum",
.{
- .tag = .int_to_enum,
- .param_count = 1,
+ "@intToEnum",
+ .{
+ .tag = .int_to_enum,
+ .param_count = 1,
+ },
},
- },
- .{
- "@intToError",
.{
- .tag = .int_to_error,
- .param_count = 1,
+ "@intToError",
+ .{
+ .tag = .int_to_error,
+ .param_count = 1,
+ },
},
- },
- .{
- "@intToFloat",
.{
- .tag = .int_to_float,
- .param_count = 1,
+ "@intToFloat",
+ .{
+ .tag = .int_to_float,
+ .param_count = 1,
+ },
},
- },
- .{
- "@intToPtr",
.{
- .tag = .int_to_ptr,
- .param_count = 2,
+ "@intToPtr",
+ .{
+ .tag = .int_to_ptr,
+ .param_count = 2,
+ },
},
- },
- .{
- "@memcpy",
.{
- .tag = .memcpy,
- .param_count = 3,
+ "@memcpy",
+ .{
+ .tag = .memcpy,
+ .param_count = 3,
+ },
},
- },
- .{
- "@memset",
.{
- .tag = .memset,
- .param_count = 3,
+ "@memset",
+ .{
+ .tag = .memset,
+ .param_count = 3,
+ },
},
- },
- .{
- "@wasmMemorySize",
.{
- .tag = .wasm_memory_size,
- .param_count = 1,
+ "@wasmMemorySize",
+ .{
+ .tag = .wasm_memory_size,
+ .param_count = 1,
+ },
},
- },
- .{
- "@wasmMemoryGrow",
.{
- .tag = .wasm_memory_grow,
- .param_count = 2,
+ "@wasmMemoryGrow",
+ .{
+ .tag = .wasm_memory_grow,
+ .param_count = 2,
+ },
},
- },
- .{
- "@mod",
.{
- .tag = .mod,
- .param_count = 2,
+ "@mod",
+ .{
+ .tag = .mod,
+ .param_count = 2,
+ },
},
- },
- .{
- "@mulWithOverflow",
.{
- .tag = .mul_with_overflow,
- .param_count = 4,
+ "@mulWithOverflow",
+ .{
+ .tag = .mul_with_overflow,
+ .param_count = 4,
+ },
},
- },
- .{
- "@panic",
.{
- .tag = .panic,
- .param_count = 1,
+ "@panic",
+ .{
+ .tag = .panic,
+ .param_count = 1,
+ },
},
- },
- .{
- "@popCount",
.{
- .tag = .pop_count,
- .param_count = 2,
+ "@popCount",
+ .{
+ .tag = .pop_count,
+ .param_count = 2,
+ },
},
- },
- .{
- "@ptrCast",
.{
- .tag = .ptr_cast,
- .param_count = 2,
+ "@ptrCast",
+ .{
+ .tag = .ptr_cast,
+ .param_count = 2,
+ },
},
- },
- .{
- "@ptrToInt",
.{
- .tag = .ptr_to_int,
- .param_count = 1,
+ "@ptrToInt",
+ .{
+ .tag = .ptr_to_int,
+ .param_count = 1,
+ },
},
- },
- .{
- "@rem",
.{
- .tag = .rem,
- .param_count = 2,
+ "@rem",
+ .{
+ .tag = .rem,
+ .param_count = 2,
+ },
},
- },
- .{
- "@returnAddress",
.{
- .tag = .return_address,
- .param_count = 0,
+ "@returnAddress",
+ .{
+ .tag = .return_address,
+ .param_count = 0,
+ },
},
- },
- .{
- "@setAlignStack",
.{
- .tag = .set_align_stack,
- .param_count = 1,
+ "@setAlignStack",
+ .{
+ .tag = .set_align_stack,
+ .param_count = 1,
+ },
},
- },
- .{
- "@setCold",
.{
- .tag = .set_cold,
- .param_count = 1,
+ "@setCold",
+ .{
+ .tag = .set_cold,
+ .param_count = 1,
+ },
},
- },
- .{
- "@setEvalBranchQuota",
.{
- .tag = .set_eval_branch_quota,
- .param_count = 1,
+ "@setEvalBranchQuota",
+ .{
+ .tag = .set_eval_branch_quota,
+ .param_count = 1,
+ },
},
- },
- .{
- "@setFloatMode",
.{
- .tag = .set_float_mode,
- .param_count = 1,
+ "@setFloatMode",
+ .{
+ .tag = .set_float_mode,
+ .param_count = 1,
+ },
},
- },
- .{
- "@setRuntimeSafety",
.{
- .tag = .set_runtime_safety,
- .param_count = 1,
+ "@setRuntimeSafety",
+ .{
+ .tag = .set_runtime_safety,
+ .param_count = 1,
+ },
},
- },
- .{
- "@shlExact",
.{
- .tag = .shl_exact,
- .param_count = 2,
+ "@shlExact",
+ .{
+ .tag = .shl_exact,
+ .param_count = 2,
+ },
},
- },
- .{
- "@shlWithOverflow",
.{
- .tag = .shl_with_overflow,
- .param_count = 4,
+ "@shlWithOverflow",
+ .{
+ .tag = .shl_with_overflow,
+ .param_count = 4,
+ },
},
- },
- .{
- "@shrExact",
.{
- .tag = .shr_exact,
- .param_count = 2,
+ "@shrExact",
+ .{
+ .tag = .shr_exact,
+ .param_count = 2,
+ },
},
- },
- .{
- "@shuffle",
.{
- .tag = .shuffle,
- .param_count = 4,
+ "@shuffle",
+ .{
+ .tag = .shuffle,
+ .param_count = 4,
+ },
},
- },
- .{
- "@sizeOf",
.{
- .tag = .size_of,
- .param_count = 1,
+ "@sizeOf",
+ .{
+ .tag = .size_of,
+ .param_count = 1,
+ },
},
- },
- .{
- "@splat",
.{
- .tag = .splat,
- .needs_mem_loc = true,
- .param_count = 2,
+ "@splat",
+ .{
+ .tag = .splat,
+ .needs_mem_loc = true,
+ .param_count = 2,
+ },
},
- },
- .{
- "@reduce",
.{
- .tag = .reduce,
- .param_count = 2,
+ "@reduce",
+ .{
+ .tag = .reduce,
+ .param_count = 2,
+ },
},
- },
- .{
- "@src",
.{
- .tag = .src,
- .needs_mem_loc = true,
- .param_count = 0,
+ "@src",
+ .{
+ .tag = .src,
+ .needs_mem_loc = true,
+ .param_count = 0,
+ },
},
- },
- .{
- "@sqrt",
.{
- .tag = .sqrt,
- .param_count = 1,
+ "@sqrt",
+ .{
+ .tag = .sqrt,
+ .param_count = 1,
+ },
},
- },
- .{
- "@sin",
.{
- .tag = .sin,
- .param_count = 1,
+ "@sin",
+ .{
+ .tag = .sin,
+ .param_count = 1,
+ },
},
- },
- .{
- "@cos",
.{
- .tag = .cos,
- .param_count = 1,
+ "@cos",
+ .{
+ .tag = .cos,
+ .param_count = 1,
+ },
},
- },
- .{
- "@exp",
.{
- .tag = .exp,
- .param_count = 1,
+ "@exp",
+ .{
+ .tag = .exp,
+ .param_count = 1,
+ },
},
- },
- .{
- "@exp2",
.{
- .tag = .exp2,
- .param_count = 1,
+ "@exp2",
+ .{
+ .tag = .exp2,
+ .param_count = 1,
+ },
},
- },
- .{
- "@log",
.{
- .tag = .log,
- .param_count = 1,
+ "@log",
+ .{
+ .tag = .log,
+ .param_count = 1,
+ },
},
- },
- .{
- "@log2",
.{
- .tag = .log2,
- .param_count = 1,
+ "@log2",
+ .{
+ .tag = .log2,
+ .param_count = 1,
+ },
},
- },
- .{
- "@log10",
.{
- .tag = .log10,
- .param_count = 1,
+ "@log10",
+ .{
+ .tag = .log10,
+ .param_count = 1,
+ },
},
- },
- .{
- "@fabs",
.{
- .tag = .fabs,
- .param_count = 1,
+ "@fabs",
+ .{
+ .tag = .fabs,
+ .param_count = 1,
+ },
},
- },
- .{
- "@floor",
.{
- .tag = .floor,
- .param_count = 1,
+ "@floor",
+ .{
+ .tag = .floor,
+ .param_count = 1,
+ },
},
- },
- .{
- "@ceil",
.{
- .tag = .ceil,
- .param_count = 1,
+ "@ceil",
+ .{
+ .tag = .ceil,
+ .param_count = 1,
+ },
},
- },
- .{
- "@trunc",
.{
- .tag = .trunc,
- .param_count = 1,
+ "@trunc",
+ .{
+ .tag = .trunc,
+ .param_count = 1,
+ },
},
- },
- .{
- "@round",
.{
- .tag = .round,
- .param_count = 1,
+ "@round",
+ .{
+ .tag = .round,
+ .param_count = 1,
+ },
},
- },
- .{
- "@subWithOverflow",
.{
- .tag = .sub_with_overflow,
- .param_count = 4,
+ "@subWithOverflow",
+ .{
+ .tag = .sub_with_overflow,
+ .param_count = 4,
+ },
},
- },
- .{
- "@tagName",
.{
- .tag = .tag_name,
- .param_count = 1,
+ "@tagName",
+ .{
+ .tag = .tag_name,
+ .param_count = 1,
+ },
},
- },
- .{
- "@This",
.{
- .tag = .This,
- .param_count = 0,
+ "@This",
+ .{
+ .tag = .This,
+ .param_count = 0,
+ },
},
- },
- .{
- "@truncate",
.{
- .tag = .truncate,
- .param_count = 2,
+ "@truncate",
+ .{
+ .tag = .truncate,
+ .param_count = 2,
+ },
},
- },
- .{
- "@Type",
.{
- .tag = .Type,
- .param_count = 1,
+ "@Type",
+ .{
+ .tag = .Type,
+ .param_count = 1,
+ },
},
- },
- .{
- "@typeInfo",
.{
- .tag = .type_info,
- .param_count = 1,
+ "@typeInfo",
+ .{
+ .tag = .type_info,
+ .param_count = 1,
+ },
},
- },
- .{
- "@typeName",
.{
- .tag = .type_name,
- .param_count = 1,
+ "@typeName",
+ .{
+ .tag = .type_name,
+ .param_count = 1,
+ },
},
- },
- .{
- "@TypeOf",
.{
- .tag = .TypeOf,
- .param_count = null,
+ "@TypeOf",
+ .{
+ .tag = .TypeOf,
+ .param_count = null,
+ },
},
- },
- .{
- "@unionInit",
.{
- .tag = .union_init,
- .needs_mem_loc = true,
- .param_count = 3,
+ "@unionInit",
+ .{
+ .tag = .union_init,
+ .needs_mem_loc = true,
+ .param_count = 3,
+ },
},
- },
-});
+ });
+};
diff --git a/src/Module.zig b/src/Module.zig
index d2530d7df3..35819c5d44 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -430,12 +430,12 @@ pub const Scope = struct {
/// Asserts the scope is a child of a File and has an AST tree and returns the tree.
pub fn tree(self: *Scope) *const ast.Tree {
switch (self.tag) {
- .file => return self.cast(File).?.tree,
- .block => return self.cast(Block).?.src_decl.container.file_scope.tree,
- .gen_zir => return self.cast(GenZIR).?.decl.container.file_scope.tree,
- .local_val => return self.cast(LocalVal).?.gen_zir.decl.container.file_scope.tree,
- .local_ptr => return self.cast(LocalPtr).?.gen_zir.decl.container.file_scope.tree,
- .container => return self.cast(Container).?.file_scope.tree,
+ .file => return &self.cast(File).?.tree,
+ .block => return &self.cast(Block).?.src_decl.container.file_scope.tree,
+ .gen_zir => return &self.cast(GenZIR).?.decl.container.file_scope.tree,
+ .local_val => return &self.cast(LocalVal).?.gen_zir.decl.container.file_scope.tree,
+ .local_ptr => return &self.cast(LocalPtr).?.gen_zir.decl.container.file_scope.tree,
+ .container => return &self.cast(Container).?.file_scope.tree,
}
}
@@ -1612,6 +1612,7 @@ fn astgenAndSemaVarDecl(
.decl = decl,
.arena = &type_scope_arena.allocator,
.parent = &decl.container.base,
+ .force_comptime = true,
};
defer type_scope.instructions.deinit(mod.gpa);
@@ -1630,7 +1631,7 @@ fn astgenAndSemaVarDecl(
} else {
return mod.failTok(
&block_scope.base,
- tree.firstToken(var_decl),
+ var_decl.ast.mut_token,
"unable to infer variable type",
.{},
);
@@ -1639,7 +1640,7 @@ fn astgenAndSemaVarDecl(
if (is_mutable and !var_info.ty.isValidVarType(is_extern)) {
return mod.failTok(
&block_scope.base,
- tree.firstToken(var_decl),
+ var_decl.ast.mut_token,
"variable of type '{}' must be const",
.{var_info.ty},
);
diff --git a/src/astgen.zig b/src/astgen.zig
index a018d58d2f..3e5d63796f 100644
--- a/src/astgen.zig
+++ b/src/astgen.zig
@@ -59,6 +59,8 @@ pub const ResultLoc = union(enum) {
pub fn typeExpr(mod: *Module, scope: *Scope, type_node: ast.Node.Index) InnerError!*zir.Inst {
const tree = scope.tree();
+ const token_starts = tree.tokens.items(.start);
+
const type_src = token_starts[tree.firstToken(type_node)];
const type_type = try addZIRInstConst(mod, scope, type_src, .{
.ty = Type.initTag(.type),
@@ -76,13 +78,17 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
.root => unreachable,
.@"usingnamespace" => unreachable,
.test_decl => unreachable,
- .doc_comment => unreachable,
- .var_decl => unreachable,
+ .global_var_decl => unreachable,
+ .local_var_decl => unreachable,
+ .simple_var_decl => unreachable,
+ .aligned_var_decl => unreachable,
.switch_case => unreachable,
- .switch_else => unreachable,
+ .switch_case_one => unreachable,
.container_field_init => unreachable,
.container_field_align => unreachable,
.container_field => unreachable,
+ .asm_output => unreachable,
+ .asm_input => unreachable,
.assign,
.assign_bit_and,
@@ -122,58 +128,107 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
.bool_and,
.bool_or,
.@"asm",
+ .asm_simple,
.string_literal,
.integer_literal,
.call,
- .@"unreachable",
+ .call_comma,
+ .async_call,
+ .async_call_comma,
+ .call_one,
+ .call_one_comma,
+ .async_call_one,
+ .async_call_one_comma,
+ .unreachable_literal,
.@"return",
.@"if",
+ .if_simple,
.@"while",
+ .while_simple,
+ .while_cont,
.bool_not,
.address_of,
.float_literal,
.undefined_literal,
- .bool_literal,
+ .true_literal,
+ .false_literal,
.null_literal,
.optional_type,
.block,
- .labeled_block,
+ .block_semicolon,
+ .block_two,
+ .block_two_semicolon,
.@"break",
- .PtrType,
+ .ptr_type_aligned,
+ .ptr_type_sentinel,
+ .ptr_type,
+ .ptr_type_bit_range,
.array_type,
.array_type_sentinel,
.enum_literal,
- .MultilineStringLiteral,
+ .multiline_string_literal,
.char_literal,
.@"defer",
+ .@"errdefer",
.@"catch",
.error_union,
.merge_error_sets,
- .range,
+ .switch_range,
.@"await",
.bit_not,
.negation,
.negation_wrap,
.@"resume",
.@"try",
- .slice_type,
.slice,
- .ArrayInitializer,
- .ArrayInitializerDot,
- .StructInitializer,
- .StructInitializerDot,
+ .slice_open,
+ .slice_sentinel,
+ .array_init_one,
+ .array_init_one_comma,
+ .array_init_dot_two,
+ .array_init_dot_two_comma,
+ .array_init_dot,
+ .array_init_dot_comma,
+ .array_init,
+ .array_init_comma,
+ .struct_init_one,
+ .struct_init_one_comma,
+ .struct_init_dot_two,
+ .struct_init_dot_two_comma,
+ .struct_init_dot,
+ .struct_init_dot_comma,
+ .struct_init,
+ .struct_init_comma,
.@"switch",
+ .switch_comma,
.@"for",
+ .for_simple,
.@"suspend",
.@"continue",
.@"anytype",
- .error_type,
- .FnProto,
+ .fn_proto_simple,
+ .fn_proto_multi,
+ .fn_proto_one,
+ .fn_proto,
+ .fn_decl,
.anyframe_type,
+ .anyframe_literal,
.error_set_decl,
- .ContainerDecl,
+ .container_decl,
+ .container_decl_comma,
+ .container_decl_two,
+ .container_decl_two_comma,
+ .container_decl_arg,
+ .container_decl_arg_comma,
+ .tagged_union,
+ .tagged_union_comma,
+ .tagged_union_two,
+ .tagged_union_two_comma,
+ .tagged_union_enum_tag,
+ .tagged_union_enum_tag_comma,
.@"comptime",
.@"nosuspend",
+ .error_value,
=> return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}),
.builtin_call,
@@ -192,10 +247,10 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
}
},
- // can be assigned to
+ // These can be assigned to.
.unwrap_optional,
.deref,
- .period,
+ .field_access,
.array_access,
.identifier,
.grouped_expression,
@@ -210,22 +265,33 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.I
/// result instruction can be used to inspect whether it is isNoReturn() but that is it,
/// it must otherwise not be used.
pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!*zir.Inst {
- switch (node.tag) {
+ const tree = scope.tree();
+ const main_tokens = tree.nodes.items(.main_token);
+ const token_tags = tree.tokens.items(.tag);
+ const node_datas = tree.nodes.items(.data);
+ const node_tags = tree.nodes.items(.tag);
+ const token_starts = tree.tokens.items(.start);
+
+ switch (node_tags[node]) {
.root => unreachable, // Top-level declaration.
.@"usingnamespace" => unreachable, // Top-level declaration.
.test_decl => unreachable, // Top-level declaration.
- .doc_comment => unreachable, // Top-level declaration.
- .var_decl => unreachable, // Handled in `blockExpr`.
+ .container_field_init => unreachable, // Top-level declaration.
+ .container_field_align => unreachable, // Top-level declaration.
+ .container_field => unreachable, // Top-level declaration.
+ .fn_decl => unreachable, // Top-level declaration.
+
+ .global_var_decl => unreachable, // Handled in `blockExpr`.
+ .local_var_decl => unreachable, // Handled in `blockExpr`.
+ .simple_var_decl => unreachable, // Handled in `blockExpr`.
+ .aligned_var_decl => unreachable, // Handled in `blockExpr`.
+
.switch_case => unreachable, // Handled in `switchExpr`.
- .switch_else => unreachable, // Handled in `switchExpr`.
- .range => unreachable, // Handled in `switchExpr`.
- .Else => unreachable, // Handled explicitly the control flow expression functions.
- .Payload => unreachable, // Handled explicitly.
- .PointerPayload => unreachable, // Handled explicitly.
- .PointerIndexPayload => unreachable, // Handled explicitly.
- .ErrorTag => unreachable, // Handled explicitly.
- .FieldInitializer => unreachable, // Handled explicitly.
- .ContainerField => unreachable, // Handled explicitly.
+ .switch_case_one => unreachable, // Handled in `switchExpr`.
+ .switch_range => unreachable, // Handled in `switchExpr`.
+
+ .asm_output => unreachable, // Handled in `asmExpr`.
+ .asm_input => unreachable, // Handled in `asmExpr`.
.assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node)),
.assign_bit_and => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_and)),
@@ -276,30 +342,28 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
.identifier => return identifier(mod, scope, rl, node),
- .asm_simple => return assembly(mod, scope, rl, tree.asmSimple(node)),
- .@"asm" => return assembly(mod, scope, rl, tree.asmFull(node)),
+ .asm_simple => return asmExpr(mod, scope, rl, tree.asmSimple(node)),
+ .@"asm" => return asmExpr(mod, scope, rl, tree.asmFull(node)),
.string_literal => return stringLiteral(mod, scope, rl, node),
.multiline_string_literal => return multilineStringLiteral(mod, scope, rl, node),
.integer_literal => return integerLiteral(mod, scope, rl, node),
- .builtin_call => return builtinCall(mod, scope, rl, node),
-
.builtin_call_two, .builtin_call_two_comma => {
- if (datas[node].lhs == 0) {
+ if (node_datas[node].lhs == 0) {
const params = [_]ast.Node.Index{};
return builtinCall(mod, scope, rl, node, &params);
- } else if (datas[node].rhs == 0) {
- const params = [_]ast.Node.Index{datas[node].lhs};
+ } else if (node_datas[node].rhs == 0) {
+ const params = [_]ast.Node.Index{node_datas[node].lhs};
return builtinCall(mod, scope, rl, node, &params);
} else {
- const params = [_]ast.Node.Index{ datas[node].lhs, datas[node].rhs };
+ const params = [_]ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs };
return builtinCall(mod, scope, rl, node, &params);
}
},
.builtin_call, .builtin_call_comma => {
- const params = tree.extra_data[datas[node].lhs..datas[node].rhs];
+ const params = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs];
return builtinCall(mod, scope, rl, node, params);
},
@@ -311,20 +375,20 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
return callExpr(mod, scope, rl, tree.callFull(node));
},
- .@"unreachable" => {
+ .unreachable_literal => {
const main_token = main_tokens[node];
const src = token_starts[main_token];
return addZIRNoOp(mod, scope, src, .unreachable_safe);
},
.@"return" => return ret(mod, scope, node),
- .period => return field(mod, scope, rl, node),
+ .field_access => return field(mod, scope, rl, node),
.float_literal => return floatLiteral(mod, scope, rl, node),
.if_simple => return ifExpr(mod, scope, rl, tree.ifSimple(node)),
- .@"if" => return ifExpr(mode, scope, rl, tree.ifFull(node)),
+ .@"if" => return ifExpr(mod, scope, rl, tree.ifFull(node)),
.while_simple => return whileExpr(mod, scope, rl, tree.whileSimple(node)),
- .while_cont => return whileExpr(mod, scope, tree.whileCont(node)),
+ .while_cont => return whileExpr(mod, scope, rl, tree.whileCont(node)),
.@"while" => return whileExpr(mod, scope, rl, tree.whileFull(node)),
.for_simple => return forExpr(mod, scope, rl, tree.forSimple(node)),
@@ -389,7 +453,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
return rvalue(mod, scope, rl, result);
},
.unwrap_optional => {
- const operand = try expr(mod, scope, rl, node.lhs);
+ const operand = try expr(mod, scope, rl, node_datas[node].lhs);
const op: zir.Inst.Tag = switch (rl) {
.ref => .optional_payload_safe_ptr,
else => .optional_payload_safe,
@@ -449,7 +513,7 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
},
.@"catch" => {
const catch_token = main_tokens[node];
- const payload_token: ?TokenIndex = if (token_tags[catch_token + 1] == .pipe)
+ const payload_token: ?ast.TokenIndex = if (token_tags[catch_token + 1] == .pipe)
catch_token + 2
else
null;
@@ -506,6 +570,34 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
null,
),
},
+
+ .ptr_type_aligned => return ptrType(mod, scope, rl, tree.ptrTypeAligned(node)),
+ .ptr_type_sentinel => return ptrType(mod, scope, rl, tree.ptrTypeSentinel(node)),
+ .ptr_type => return ptrType(mod, scope, rl, tree.ptrType(node)),
+ .ptr_type_bit_range => return ptrType(mod, scope, rl, tree.ptrTypeBitRange(node)),
+
+ .container_decl,
+ .container_decl_comma,
+ => return containerDecl(mod, scope, rl, tree.containerDecl(node)),
+ .container_decl_two, .container_decl_two_comma => {
+ var buffer: [2]ast.Node.Index = undefined;
+ return containerDecl(mod, scope, rl, tree.containerDeclTwo(&buffer, node));
+ },
+ .container_decl_arg,
+ .container_decl_arg_comma,
+ => return containerDecl(mod, scope, rl, tree.containerDeclArg(node)),
+
+ .tagged_union,
+ .tagged_union_comma,
+ => return containerDecl(mod, scope, rl, tree.taggedUnion(node)),
+ .tagged_union_two, .tagged_union_two_comma => {
+ var buffer: [2]ast.Node.Index = undefined;
+ return containerDecl(mod, scope, rl, tree.taggedUnionTwo(&buffer, node));
+ },
+ .tagged_union_enum_tag,
+ .tagged_union_enum_tag_comma,
+ => return containerDecl(mod, scope, rl, tree.taggedUnionEnumTag(node)),
+
.@"break" => return breakExpr(mod, scope, rl, node),
.@"continue" => return continueExpr(mod, scope, rl, node),
.grouped_expression => return expr(mod, scope, rl, node_datas[node].lhs),
@@ -518,12 +610,41 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In
.@"switch", .switch_comma => return switchExpr(mod, scope, rl, node),
.@"defer" => return mod.failNode(scope, node, "TODO implement astgen.expr for .defer", .{}),
+ .@"errdefer" => return mod.failNode(scope, node, "TODO implement astgen.expr for .errdefer", .{}),
.@"await" => return mod.failNode(scope, node, "TODO implement astgen.expr for .await", .{}),
.@"resume" => return mod.failNode(scope, node, "TODO implement astgen.expr for .resume", .{}),
.@"try" => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}),
+
+ .array_init_one,
+ .array_init_one_comma,
+ .array_init_dot_two,
+ .array_init_dot_two_comma,
+ .array_init_dot,
+ .array_init_dot_comma,
+ .array_init,
+ .array_init_comma,
+ => return mod.failNode(scope, node, "TODO implement astgen.expr for array literals", .{}),
+
+ .struct_init_one,
+ .struct_init_one_comma,
+ .struct_init_dot_two,
+ .struct_init_dot_two_comma,
+ .struct_init_dot,
+ .struct_init_dot_comma,
+ .struct_init,
+ .struct_init_comma,
+ => return mod.failNode(scope, node, "TODO implement astgen.expr for struct literals", .{}),
+
.@"suspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .suspend", .{}),
.@"anytype" => return mod.failNode(scope, node, "TODO implement astgen.expr for .anytype", .{}),
+ .fn_proto_simple,
+ .fn_proto_multi,
+ .fn_proto_one,
+ .fn_proto,
+ => return mod.failNode(scope, node, "TODO implement astgen.expr for function prototypes", .{}),
+
.@"nosuspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .nosuspend", .{}),
+ .error_value => return mod.failNode(scope, node, "TODO implement astgen.expr for .error_value", .{}),
}
}
@@ -572,6 +693,8 @@ fn breakExpr(
const tree = parent_scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+
const src = token_starts[main_tokens[node]];
const break_label = node_datas[node].lhs;
const rhs = node_datas[node].rhs;
@@ -646,6 +769,8 @@ fn continueExpr(
const tree = parent_scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+
const src = token_starts[main_tokens[node]];
const break_label = node_datas[node].lhs;
@@ -702,7 +827,7 @@ pub fn blockExpr(
const main_tokens = tree.nodes.items(.main_token);
const token_tags = tree.tokens.items(.tag);
- const lbrace = main_tokens[node];
+ const lbrace = main_tokens[block_node];
if (token_tags[lbrace - 1] == .colon) {
return labeledBlockExpr(mod, scope, rl, block_node, statements, .block);
}
@@ -721,8 +846,9 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn
if (gen_zir.label) |prev_label| {
if (try tokenIdentEql(mod, parent_scope, label, prev_label.token)) {
const tree = parent_scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+
const label_src = token_starts[label];
const prev_label_src = token_starts[prev_label.token];
@@ -770,9 +896,9 @@ fn labeledBlockExpr(
assert(zir_tag == .block or zir_tag == .block_comptime);
const tree = parent_scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
const token_starts = tree.tokens.items(.start);
+ const token_tags = tree.tokens.items(.tag);
const lbrace = main_tokens[block_node];
const label_token = lbrace - 1;
@@ -813,10 +939,10 @@ fn labeledBlockExpr(
defer block_scope.labeled_breaks.deinit(mod.gpa);
defer block_scope.labeled_store_to_block_ptr_list.deinit(mod.gpa);
- try blockExprStmts(mod, &block_scope.base, block_node, block_node.statements());
+ try blockExprStmts(mod, &block_scope.base, block_node, statements);
if (!block_scope.label.?.used) {
- return mod.fail(parent_scope, token_starts[block_node.label], "unused block label", .{});
+ return mod.failTok(parent_scope, label_token, "unused block label", .{});
}
try gen_zir.instructions.append(mod.gpa, &block_inst.base);
@@ -860,21 +986,23 @@ fn blockExprStmts(
statements: []const ast.Node.Index,
) !void {
const tree = parent_scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+ const node_tags = tree.nodes.items(.tag);
var block_arena = std.heap.ArenaAllocator.init(mod.gpa);
defer block_arena.deinit();
var scope = parent_scope;
for (statements) |statement| {
- const src = token_starts[statement.firstToken()];
+ const src = token_starts[tree.firstToken(statement)];
_ = try addZIRNoOp(mod, scope, src, .dbg_stmt);
- switch (statement.tag) {
- .var_decl => {
- const var_decl_node = statement.castTag(.var_decl).?;
- scope = try varDecl(mod, scope, var_decl_node, &block_arena.allocator);
- },
+ switch (node_tags[statement]) {
+ .global_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.globalVarDecl(statement)),
+ .local_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.localVarDecl(statement)),
+ .simple_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.simpleVarDecl(statement)),
+ .aligned_var_decl => scope = try varDecl(mod, scope, &block_arena.allocator, tree.alignedVarDecl(statement)),
+
.assign => try assign(mod, scope, statement),
.assign_bit_and => try assignOp(mod, scope, statement, .bit_and),
.assign_bit_or => try assignOp(mod, scope, statement, .bit_or),
@@ -903,20 +1031,23 @@ fn blockExprStmts(
fn varDecl(
mod: *Module,
scope: *Scope,
- node: *ast.Node.var_decl,
block_arena: *Allocator,
+ var_decl: ast.full.VarDecl,
) InnerError!*Scope {
- if (node.getComptimeToken()) |comptime_token| {
+ if (var_decl.comptime_token) |comptime_token| {
return mod.failTok(scope, comptime_token, "TODO implement comptime locals", .{});
}
- if (node.getAlignNode()) |align_node| {
- return mod.failNode(scope, align_node, "TODO implement alignment on locals", .{});
+ if (var_decl.ast.align_node != 0) {
+ return mod.failNode(scope, var_decl.ast.align_node, "TODO implement alignment on locals", .{});
}
const tree = scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
- const name_src = token_starts[node.name_token];
- const ident_name = try mod.identifierTokenString(scope, node.name_token);
+ const token_starts = tree.tokens.items(.start);
+ const token_tags = tree.tokens.items(.tag);
+
+ const name_token = var_decl.ast.mut_token + 1;
+ const name_src = token_starts[name_token];
+ const ident_name = try mod.identifierTokenString(scope, name_token);
// Local variables shadowing detection, including function parameters.
{
@@ -962,20 +1093,21 @@ fn varDecl(
// TODO add note for other definition
return mod.fail(scope, name_src, "redefinition of '{s}'", .{ident_name});
}
- const init_node = node.getInitNode() orelse
+ if (var_decl.ast.init_node == 0) {
return mod.fail(scope, name_src, "variables must be initialized", .{});
+ }
- switch (tree.token_ids[node.mut_token]) {
+ switch (token_tags[var_decl.ast.mut_token]) {
.keyword_const => {
// Depending on the type of AST the initialization expression is, we may need an lvalue
// or an rvalue as a result location. If it is an rvalue, we can use the instruction as
// the variable, no memory location needed.
- if (!nodeMayNeedMemoryLocation(init_node, scope)) {
- const result_loc: ResultLoc = if (node.getTypeNode()) |type_node|
- .{ .ty = try typeExpr(mod, scope, type_node) }
+ if (!nodeMayNeedMemoryLocation(scope, var_decl.ast.init_node)) {
+ const result_loc: ResultLoc = if (var_decl.ast.type_node != 0)
+ .{ .ty = try typeExpr(mod, scope, var_decl.ast.type_node) }
else
.none;
- const init_inst = try expr(mod, scope, result_loc, init_node);
+ const init_inst = try expr(mod, scope, result_loc, var_decl.ast.init_node);
const sub_scope = try block_arena.create(Scope.LocalVal);
sub_scope.* = .{
.parent = scope,
@@ -999,8 +1131,8 @@ fn varDecl(
var resolve_inferred_alloc: ?*zir.Inst = null;
var opt_type_inst: ?*zir.Inst = null;
- if (node.getTypeNode()) |type_node| {
- const type_inst = try typeExpr(mod, &init_scope.base, type_node);
+ if (var_decl.ast.type_node != 0) {
+ const type_inst = try typeExpr(mod, &init_scope.base, var_decl.ast.type_node);
opt_type_inst = type_inst;
init_scope.rl_ptr = try addZIRUnOp(mod, &init_scope.base, name_src, .alloc, type_inst);
} else {
@@ -1009,7 +1141,7 @@ fn varDecl(
init_scope.rl_ptr = &alloc.base;
}
const init_result_loc: ResultLoc = .{ .block_ptr = &init_scope };
- const init_inst = try expr(mod, &init_scope.base, init_result_loc, init_node);
+ const init_inst = try expr(mod, &init_scope.base, init_result_loc, var_decl.ast.init_node);
const parent_zir = &scope.getGenZIR().instructions;
if (init_scope.rvalue_rl_count == 1) {
// Result location pointer not used. We don't need an alloc for this
@@ -1069,8 +1201,11 @@ fn varDecl(
},
.keyword_var => {
var resolve_inferred_alloc: ?*zir.Inst = null;
- const var_data: struct { result_loc: ResultLoc, alloc: *zir.Inst } = if (node.getTypeNode()) |type_node| a: {
- const type_inst = try typeExpr(mod, scope, type_node);
+ const var_data: struct {
+ result_loc: ResultLoc,
+ alloc: *zir.Inst,
+ } = if (var_decl.ast.type_node != 0) a: {
+ const type_inst = try typeExpr(mod, scope, var_decl.ast.type_node);
const alloc = try addZIRUnOp(mod, scope, name_src, .alloc_mut, type_inst);
break :a .{ .alloc = alloc, .result_loc = .{ .ptr = alloc } };
} else a: {
@@ -1078,7 +1213,7 @@ fn varDecl(
resolve_inferred_alloc = &alloc.base;
break :a .{ .alloc = &alloc.base, .result_loc = .{ .inferred_ptr = alloc } };
};
- const init_inst = try expr(mod, scope, var_data.result_loc, init_node);
+ const init_inst = try expr(mod, scope, var_data.result_loc, var_decl.ast.init_node);
if (resolve_inferred_alloc) |inst| {
_ = try addZIRUnOp(mod, scope, name_src, .resolve_inferred_alloc, inst);
}
@@ -1099,13 +1234,15 @@ fn assign(mod: *Module, scope: *Scope, infix_node: ast.Node.Index) InnerError!vo
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const node_tags = tree.nodes.items(.tag);
+
const lhs = node_datas[infix_node].lhs;
const rhs = node_datas[infix_node].rhs;
if (node_tags[lhs] == .identifier) {
// This intentionally does not support `@"_"` syntax.
const ident_name = tree.tokenSlice(main_tokens[lhs]);
if (mem.eql(u8, ident_name, "_")) {
- _ = try expr(mod, scope, .discard, infix_node.rhs);
+ _ = try expr(mod, scope, .discard, rhs);
return;
}
}
@@ -1122,6 +1259,7 @@ fn assignOp(
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
const lhs_ptr = try lvalExpr(mod, scope, node_datas[infix_node].lhs);
const lhs = try addZIRUnOp(mod, scope, lhs_ptr.src, .deref, lhs_ptr);
@@ -1136,6 +1274,7 @@ fn boolNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.In
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
const src = token_starts[main_tokens[node]];
const bool_type = try addZIRInstConst(mod, scope, src, .{
@@ -1150,6 +1289,7 @@ fn bitNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Ins
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
const src = token_starts[main_tokens[node]];
const operand = try expr(mod, scope, .none, node_datas[node].lhs);
@@ -1165,6 +1305,7 @@ fn negation(
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
const src = token_starts[main_tokens[node]];
const lhs = try addZIRInstConst(mod, scope, src, .{
@@ -1175,53 +1316,61 @@ fn negation(
return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs);
}
-fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, rhs: *ast.Node, size: std.builtin.TypeInfo.Pointer.Size) InnerError!*zir.Inst {
+fn ptrType(
+ mod: *Module,
+ scope: *Scope,
+ rl: ResultLoc,
+ ptr_info: ast.full.PtrType,
+) InnerError!*zir.Inst {
+ const tree = scope.tree();
+ const token_starts = tree.tokens.items(.start);
+
+ const src = token_starts[ptr_info.ast.main_token];
+
const simple = ptr_info.allowzero_token == null and
- ptr_info.align_info == null and
+ ptr_info.ast.align_node == 0 and
ptr_info.volatile_token == null and
- ptr_info.sentinel == null;
+ ptr_info.ast.sentinel == 0;
if (simple) {
- const child_type = try typeExpr(mod, scope, rhs);
+ const child_type = try typeExpr(mod, scope, ptr_info.ast.child_type);
const mutable = ptr_info.const_token == null;
- // TODO stage1 type inference bug
const T = zir.Inst.Tag;
- return addZIRUnOp(mod, scope, src, switch (size) {
+ const result = try addZIRUnOp(mod, scope, src, switch (ptr_info.size) {
.One => if (mutable) T.single_mut_ptr_type else T.single_const_ptr_type,
.Many => if (mutable) T.many_mut_ptr_type else T.many_const_ptr_type,
.C => if (mutable) T.c_mut_ptr_type else T.c_const_ptr_type,
.Slice => if (mutable) T.mut_slice_type else T.const_slice_type,
}, child_type);
+ return rvalue(mod, scope, rl, result);
}
var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, .kw_args).field_type = .{};
- kw_args.size = size;
+ kw_args.size = ptr_info.size;
kw_args.@"allowzero" = ptr_info.allowzero_token != null;
- if (ptr_info.align_info) |some| {
- kw_args.@"align" = try expr(mod, scope, .none, some.node);
- if (some.bit_range) |bit_range| {
- kw_args.align_bit_start = try expr(mod, scope, .none, bit_range.start);
- kw_args.align_bit_end = try expr(mod, scope, .none, bit_range.end);
+ if (ptr_info.ast.align_node != 0) {
+ kw_args.@"align" = try expr(mod, scope, .none, ptr_info.ast.align_node);
+ if (ptr_info.ast.bit_range_start != 0) {
+ kw_args.align_bit_start = try expr(mod, scope, .none, ptr_info.ast.bit_range_start);
+ kw_args.align_bit_end = try expr(mod, scope, .none, ptr_info.ast.bit_range_end);
}
}
kw_args.mutable = ptr_info.const_token == null;
kw_args.@"volatile" = ptr_info.volatile_token != null;
- if (ptr_info.sentinel) |some| {
- kw_args.sentinel = try expr(mod, scope, .none, some);
- }
-
- const child_type = try typeExpr(mod, scope, rhs);
- if (kw_args.sentinel) |some| {
- kw_args.sentinel = try addZIRBinOp(mod, scope, some.src, .as, child_type, some);
+ const child_type = try typeExpr(mod, scope, ptr_info.ast.child_type);
+ if (ptr_info.ast.sentinel != 0) {
+ kw_args.sentinel = try expr(mod, scope, .{ .ty = child_type }, ptr_info.ast.sentinel);
}
-
- return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
+ const result = try addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args);
+ return rvalue(mod, scope, rl, result);
}
fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
const tree = scope.tree();
const main_tokens = tree.nodes.items(.main_token);
const node_datas = tree.nodes.items(.data);
+ const token_starts = tree.tokens.items(.start);
+
const src = token_starts[main_tokens[node]];
const usize_type = try addZIRInstConst(mod, scope, src, .{
.ty = Type.initTag(.type),
@@ -1246,6 +1395,9 @@ fn arrayType(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !
fn arrayTypeSentinel(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
const tree = scope.tree();
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+ const node_datas = tree.nodes.items(.data);
+
const len_node = node_datas[node].lhs;
const extra = tree.extraData(node_datas[node].rhs, ast.Node.ArrayTypeSentinel);
const src = token_starts[main_tokens[node]];
@@ -1274,6 +1426,8 @@ fn containerField(
node: *ast.Node.ContainerField,
) InnerError!*zir.Inst {
const tree = scope.tree();
+ const token_starts = tree.tokens.items(.start);
+
const src = token_starts[tree.firstToken(node)];
const name = try mod.identifierTokenString(scope, node.name_token);
@@ -1305,9 +1459,18 @@ fn containerField(
});
}
-fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ContainerDecl) InnerError!*zir.Inst {
+fn containerDecl(
+ mod: *Module,
+ scope: *Scope,
+ rl: ResultLoc,
+ container_decl: ast.full.ContainerDecl,
+) InnerError!*zir.Inst {
const tree = scope.tree();
- const src = token_starts[node.kind_token];
+ const token_starts = tree.tokens.items(.start);
+ const node_tags = tree.nodes.items(.tag);
+ const token_tags = tree.tokens.items(.tag);
+
+ const src = token_starts[container_decl.ast.main_token];
var gen_scope: Scope.GenZIR = .{
.parent = scope,
@@ -1321,9 +1484,12 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
var fields = std.ArrayList(*zir.Inst).init(mod.gpa);
defer fields.deinit();
- for (node.fieldsAndDecls()) |fd| {
- if (fd.castTag(.ContainerField)) |f| {
- try fields.append(try containerField(mod, &gen_scope.base, f));
+ for (container_decl.ast.members) |member| {
+ switch (node_tags[member]) {
+ .container_field_init, .container_field_align, .container_field => {
+ try fields.append(try containerField(mod, &gen_scope.base, member));
+ },
+ else => continue,
}
}
@@ -1332,19 +1498,22 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
const arena = &decl_arena.allocator;
var layout: std.builtin.TypeInfo.ContainerLayout = .Auto;
- if (node.layout_token) |some| switch (tree.token_ids[some]) {
+ if (container_decl.layout_token) |some| switch (token_tags[some]) {
.keyword_extern => layout = .Extern,
.keyword_packed => layout = .Packed,
else => unreachable,
};
- const container_type = switch (tree.token_ids[node.kind_token]) {
+ // TODO this implementation is incorrect. The types must be created in semantic
+ // analysis, not astgen, because the same ZIR is re-used for multiple inline function calls,
+ // comptime function calls, and generic function instantiations, and these
+ // must result in different instances of container types.
+ const container_type = switch (token_tags[container_decl.ast.main_token]) {
.keyword_enum => blk: {
- const tag_type: ?*zir.Inst = switch (node.init_arg_expr) {
- .Type => |t| try typeExpr(mod, &gen_scope.base, t),
- .None => null,
- .Enum => unreachable,
- };
+ const tag_type: ?*zir.Inst = if (container_decl.ast.arg != 0)
+ try typeExpr(mod, &gen_scope.base, container_decl.ast.arg)
+ else
+ null;
const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.EnumType, .{
.fields = try arena.dupe(*zir.Inst, fields.items),
}, .{
@@ -1367,7 +1536,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
break :blk Type.initPayload(&enum_type.base);
},
.keyword_struct => blk: {
- assert(node.init_arg_expr == .None);
+ assert(container_decl.ast.arg == 0);
const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.StructType, .{
.fields = try arena.dupe(*zir.Inst, fields.items),
}, .{
@@ -1389,21 +1558,16 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
break :blk Type.initPayload(&struct_type.base);
},
.keyword_union => blk: {
- const init_inst = switch (node.init_arg_expr) {
- .Enum => |e| if (e) |t| try typeExpr(mod, &gen_scope.base, t) else null,
- .None => null,
- .Type => |t| try typeExpr(mod, &gen_scope.base, t),
- };
- const init_kind: zir.Inst.UnionType.InitKind = switch (node.init_arg_expr) {
- .Enum => .enum_type,
- .None => .none,
- .Type => .tag_type,
- };
+ const init_inst: ?*zir.Inst = if (container_decl.ast.arg != 0)
+ try typeExpr(mod, &gen_scope.base, container_decl.ast.arg)
+ else
+ null;
+ const has_enum_token = container_decl.ast.enum_token != null;
const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.UnionType, .{
.fields = try arena.dupe(*zir.Inst, fields.items),
}, .{
.layout = layout,
- .init_kind = init_kind,
+ .has_enum_token = has_enum_token,
.init_inst = init_inst,
});
const union_type = try arena.create(Type.Payload.Union);
@@ -1437,7 +1601,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con
else => unreachable,
};
const val = try Value.Tag.ty.create(arena, container_type);
- const decl = try mod.createContainerDecl(scope, node.kind_token, &decl_arena, .{
+ const decl = try mod.createContainerDecl(scope, container_decl.ast.main_token, &decl_arena, .{
.ty = Type.initTag(.type),
.val = val,
});
@@ -1459,6 +1623,7 @@ fn errorSetDecl(
const tree = scope.tree();
const main_tokens = tree.nodes.items(.main_token);
const token_tags = tree.tokens.items(.tag);
+ const token_starts = tree.tokens.items(.start);
// Count how many fields there are.
const error_token = main_tokens[node];
@@ -1500,15 +1665,17 @@ fn orelseCatchExpr(
mod: *Module,
scope: *Scope,
rl: ResultLoc,
- lhs: *ast.Node,
+ lhs: ast.Node.Index,
op_token: ast.TokenIndex,
cond_op: zir.Inst.Tag,
unwrap_op: zir.Inst.Tag,
unwrap_code_op: zir.Inst.Tag,
- rhs: *ast.Node,
- payload_node: ?*ast.Node,
+ rhs: ast.Node.Index,
+ payload_token: ?ast.TokenIndex,
) InnerError!*zir.Inst {
const tree = scope.tree();
+ const token_starts = tree.tokens.items(.start);
+
const src = token_starts[op_token];
var block_scope: Scope.GenZIR = .{
@@ -1547,12 +1714,11 @@ fn orelseCatchExpr(
var err_val_scope: Scope.LocalVal = undefined;
const then_sub_scope = blk: {
- const payload = payload_node orelse break :blk &then_scope.base;
-
- const err_name = tree.tokenSlice(payload.castTag(.Payload).?.error_symbol.firstToken());
- if (mem.eql(u8, err_name, "_"))
- break :blk &then_scope.base;
-
+ const payload = payload_token orelse break :blk &then_scope.base;
+ if (mem.eql(u8, tree.tokenSlice(payload), "_")) {
+ return mod.failTok(&then_scope.base, payload, "discard of error capture; omit it instead", .{});
+ }
+ const err_name = try mod.identifierTokenString(scope, payload);
err_val_scope = .{
.parent = &then_scope.base,
.gen_zir = &then_scope,
@@ -1685,18 +1851,20 @@ pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) I
const tree = scope.tree();
const token_starts = tree.tokens.items(.start);
const main_tokens = tree.nodes.items(.main_token);
+ const node_datas = tree.nodes.items(.data);
+
const dot_token = main_tokens[node];
const src = token_starts[dot_token];
const field_ident = dot_token + 1;
const field_name = try mod.identifierTokenString(scope, field_ident);
if (rl == .ref) {
return addZirInstTag(mod, scope, src, .field_ptr, .{
- .object = try expr(mod, scope, .ref, node.lhs),
+ .object = try expr(mod, scope, .ref, node_datas[node].lhs),
.field_name = field_name,
});
} else {
return rvalue(mod, scope, rl, try addZirInstTag(mod, scope, src, .field_val, .{
- .object = try expr(mod, scope, .none, node.lhs),
+ .object = try expr(mod, scope, .none, node_datas[node].lhs),
.field_name = field_name,
}));
}
@@ -1711,6 +1879,8 @@ fn arrayAccess(
const tree = scope.tree();
const main_tokens = tree.nodes.items(.main_token);
const token_starts = tree.tokens.items(.start);
+ const node_datas = tree.nodes.items(.data);
+
const src = token_starts[main_tokens[node]];
const usize_type = try addZIRInstConst(mod, scope, src, .{
.ty = Type.initTag(.type),
@@ -1737,6 +1907,7 @@ fn sliceExpr(
) InnerError!*zir.Inst {
const tree = scope.tree();
const token_starts = tree.tokens.items(.start);
+
const src = token_starts[slice.ast.lbracket];
const usize_type = try addZIRInstConst(mod, scope, src, .{
@@ -1786,6 +1957,7 @@ fn simpleBinOp(
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
const lhs = try expr(mod, scope, .none, node_datas[infix_node].lhs);
const rhs = try expr(mod, scope, .none, node_datas[infix_node].rhs);
@@ -1804,6 +1976,7 @@ fn boolBinOp(
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
const src = token_starts[main_tokens[infix_node]];
const bool_type = try addZIRInstConst(mod, scope, src, .{
@@ -1899,13 +2072,14 @@ fn ifExpr(
defer block_scope.instructions.deinit(mod.gpa);
const tree = scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+
const if_src = token_starts[if_full.ast.if_token];
const cond = c: {
// TODO https://github.com/ziglang/zig/issues/7929
- if (if_full.ast.error_token) |error_token| {
+ if (if_full.error_token) |error_token| {
return mod.failTok(scope, error_token, "TODO implement if error union", .{});
} else if (if_full.payload_token) |payload_token| {
return mod.failTok(scope, payload_token, "TODO implement if optional", .{});
@@ -1966,7 +2140,7 @@ fn ifExpr(
};
} else
.{
- .src = token_starts[tree.lastToken(if_full.then_expr)],
+ .src = token_starts[tree.lastToken(if_full.ast.then_expr)],
.result = null,
};
@@ -2042,8 +2216,9 @@ fn whileExpr(
defer continue_scope.instructions.deinit(mod.gpa);
const tree = scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+
const while_src = token_starts[while_full.ast.while_token];
const void_type = try addZIRInstConst(mod, scope, while_src, .{
.ty = Type.initTag(.type),
@@ -2051,16 +2226,16 @@ fn whileExpr(
});
const cond = c: {
// TODO https://github.com/ziglang/zig/issues/7929
- if (while_full.ast.error_token) |error_token| {
+ if (while_full.error_token) |error_token| {
return mod.failTok(scope, error_token, "TODO implement while error union", .{});
} else if (while_full.payload_token) |payload_token| {
return mod.failTok(scope, payload_token, "TODO implement while optional", .{});
} else {
- const bool_type = try addZIRInstConst(mod, &block_scope.base, while_src, .{
+ const bool_type = try addZIRInstConst(mod, &continue_scope.base, while_src, .{
.ty = Type.initTag(.type),
.val = Value.initTag(.bool_type),
});
- break :c try expr(mod, &block_scope.base, .{ .ty = bool_type }, while_full.ast.cond_expr);
+ break :c try expr(mod, &continue_scope.base, .{ .ty = bool_type }, while_full.ast.cond_expr);
}
};
@@ -2128,7 +2303,7 @@ fn whileExpr(
};
defer else_scope.instructions.deinit(mod.gpa);
- const else_node = if_full.ast.else_expr;
+ const else_node = while_full.ast.else_expr;
const else_info: struct { src: usize, result: ?*zir.Inst } = if (else_node != 0) blk: {
loop_scope.break_count += 1;
const sub_scope = &else_scope.base;
@@ -2138,7 +2313,7 @@ fn whileExpr(
};
} else
.{
- .src = token_starts[tree.lastToken(then_node)],
+ .src = token_starts[tree.lastToken(while_full.ast.then_expr)],
.result = null,
};
@@ -2181,8 +2356,10 @@ fn forExpr(
// Set up variables and constants.
const tree = scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+ const token_tags = tree.tokens.items(.tag);
+
const for_src = token_starts[for_full.ast.while_token];
const index_ptr = blk: {
const usize_type = try addZIRInstConst(mod, scope, for_src, .{
@@ -2299,7 +2476,7 @@ fn forExpr(
else
break :blk &then_scope.base;
if (mem.eql(u8, tree.tokenSlice(index_token), "_")) {
- return mod.failTok(&then_scope.base, index_token, "discard of index capture not allowed; omit it instead", .{});
+ return mod.failTok(&then_scope.base, index_token, "discard of index capture; omit it instead", .{});
}
const index_name = try mod.identifierTokenString(&then_scope.base, index_token);
index_scope = .{
@@ -2334,7 +2511,7 @@ fn forExpr(
};
} else
.{
- .src = token_starts[tree.lastToken(then_node)],
+ .src = token_starts[tree.lastToken(for_full.ast.then_expr)],
.result = null,
};
@@ -2386,10 +2563,12 @@ fn switchExpr(
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
const token_tags = tree.tokens.items(.tag);
+ const token_starts = tree.tokens.items(.start);
+ const node_tags = tree.nodes.items(.tag);
const switch_token = main_tokens[switch_node];
- const target_node = datas[switch_node].lhs;
- const extra = tree.extraData(datas[switch_node].rhs, ast.switch_node.SubRange);
+ const target_node = node_datas[switch_node].lhs;
+ const extra = tree.extraData(node_datas[switch_node].rhs, ast.Node.SubRange);
const case_nodes = tree.extra_data[extra.start..extra.end];
const switch_src = token_starts[switch_token];
@@ -2552,7 +2731,7 @@ fn switchExpr(
defer else_scope.instructions.deinit(mod.gpa);
// Now generate all but the special cases.
- var special_case: ?ast.Node.Index = null;
+ var special_case: ?ast.full.SwitchCase = null;
var items_index: usize = 0;
var case_index: usize = 0;
for (case_nodes) |case_node| {
@@ -2582,7 +2761,7 @@ fn switchExpr(
{
const item = items.items[items_index];
items_index += 1;
- try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target, target_ptr);
+ try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target);
cases[case_index] = .{
.item = item,
@@ -2638,7 +2817,7 @@ fn switchExpr(
// reset cond_scope for then_body
case_scope.instructions.items.len = 0;
- try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target, target_ptr);
+ try switchCaseExpr(mod, &case_scope.base, block_scope.break_result_loc, block, case, target);
condbr.positionals.then_body = .{
.instructions = try scope.arena().dupe(*zir.Inst, case_scope.instructions.items),
};
@@ -2655,7 +2834,7 @@ fn switchExpr(
// Finally generate else block or a break.
if (special_case) |case| {
- try switchCaseExpr(mod, &else_scope.base, block_scope.break_result_loc, block, case, target, target_ptr);
+ try switchCaseExpr(mod, &else_scope.base, block_scope.break_result_loc, block, case, target);
} else {
// Not handling all possible cases is a compile error.
_ = try addZIRNoOp(mod, &else_scope.base, switch_src, .unreachable_unsafe);
@@ -2674,11 +2853,13 @@ fn switchCaseExpr(
block: *zir.Inst.Block,
case: ast.full.SwitchCase,
target: *zir.Inst,
- target_ptr: ?*zir.Inst,
) !void {
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+ const token_tags = tree.tokens.items(.tag);
+
const case_src = token_starts[case.ast.arrow_token];
const sub_scope = blk: {
const payload_token = case.payload_token orelse break :blk scope;
@@ -2690,11 +2871,11 @@ fn switchCaseExpr(
const value_name = tree.tokenSlice(ident);
if (mem.eql(u8, value_name, "_")) {
if (is_ptr) {
- return mod.failTok(scope, payload.ptr_token.?, "pointer modifier invalid on discard", .{});
+ return mod.failTok(scope, payload_token, "pointer modifier invalid on discard", .{});
}
break :blk scope;
}
- return mod.failNode(scope, payload.value_symbol, "TODO implement switch value payload", .{});
+ return mod.failTok(scope, ident, "TODO implement switch value payload", .{});
};
const case_body = try expr(mod, sub_scope, rl, case.ast.target_expr);
@@ -2710,10 +2891,12 @@ fn ret(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst {
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+
const src = token_starts[main_tokens[node]];
const rhs_node = node_datas[node].lhs;
if (rhs_node != 0) {
- if (nodeMayNeedMemoryLocation(rhs_node, scope)) {
+ if (nodeMayNeedMemoryLocation(scope, rhs_node)) {
const ret_ptr = try addZIRNoOp(mod, scope, src, .ret_ptr);
const operand = try expr(mod, scope, .{ .ptr = ret_ptr }, rhs_node);
return addZIRUnOp(mod, scope, src, .@"return", operand);
@@ -2737,8 +2920,8 @@ fn identifier(
defer tracy.end();
const tree = scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
const ident_token = main_tokens[ident];
const ident_name = try mod.identifierTokenString(scope, ident_token);
@@ -2826,6 +3009,27 @@ fn identifier(
return mod.failNode(scope, ident, "use of undeclared identifier '{s}'", .{ident_name});
}
+fn parseStringLiteral(mod: *Module, scope: *Scope, token: ast.TokenIndex) ![]u8 {
+ const tree = scope.tree();
+ const token_tags = tree.tokens.items(.tag);
+ const token_starts = tree.tokens.items(.start);
+ assert(token_tags[token] == .string_literal);
+ const unparsed = tree.tokenSlice(token);
+ const arena = scope.arena();
+ var bad_index: usize = undefined;
+ const bytes = std.zig.parseStringLiteral(arena, unparsed, &bad_index) catch |err| switch (err) {
+ error.InvalidCharacter => {
+ const bad_byte = unparsed[bad_index];
+ const src = token_starts[token];
+ return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'", .{
+ bad_byte,
+ });
+ },
+ else => |e| return e,
+ };
+ return bytes;
+}
+
fn stringLiteral(
mod: *Module,
scope: *Scope,
@@ -2833,23 +3037,11 @@ fn stringLiteral(
str_lit: ast.Node.Index,
) InnerError!*zir.Inst {
const tree = scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
const str_lit_token = main_tokens[str_lit];
- const unparsed_bytes = tree.tokenSlice(str_lit_token);
- const arena = scope.arena();
-
- var bad_index: usize = undefined;
- const bytes = std.zig.parseStringLiteral(arena, unparsed_bytes, &bad_index) catch |err| switch (err) {
- error.InvalidCharacter => {
- const bad_byte = unparsed_bytes[bad_index];
- const src = token_starts[str_lit_token];
- return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'\n", .{bad_byte});
- },
- else => |e| return e,
- };
-
+ const bytes = try parseStringLiteral(mod, scope, str_lit_token);
const src = token_starts[str_lit_token];
const str_inst = try addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{});
return rvalue(mod, scope, rl, str_inst);
@@ -2864,9 +3056,10 @@ fn multilineStringLiteral(
const tree = scope.tree();
const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
- const start = node_datas[node].lhs;
- const end = node_datas[node].rhs;
+ const start = node_datas[str_lit].lhs;
+ const end = node_datas[str_lit].rhs;
// Count the number of bytes to allocate.
const len: usize = len: {
@@ -2905,9 +3098,10 @@ fn multilineStringLiteral(
fn charLiteral(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) !*zir.Inst {
const tree = scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
const main_token = main_tokens[node];
+ const token_starts = tree.tokens.items(.start);
+
const src = token_starts[main_token];
const slice = tree.tokenSlice(main_token);
@@ -2934,6 +3128,7 @@ fn integerLiteral(
const arena = scope.arena();
const tree = scope.tree();
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
const int_token = main_tokens[int_lit];
const prefixed_bytes = tree.tokenSlice(int_token);
@@ -2972,6 +3167,8 @@ fn floatLiteral(
const arena = scope.arena();
const tree = scope.tree();
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+
const main_token = main_tokens[float_lit];
const bytes = tree.tokenSlice(main_token);
if (bytes.len > 2 and bytes[1] == 'x') {
@@ -2988,17 +3185,18 @@ fn floatLiteral(
return rvalue(mod, scope, rl, result);
}
-fn assembly(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) InnerError!*zir.Inst {
+fn asmExpr(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) InnerError!*zir.Inst {
const arena = scope.arena();
const tree = scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+ const node_datas = tree.nodes.items(.data);
if (full.outputs.len != 0) {
return mod.failTok(scope, full.ast.asm_token, "TODO implement asm with an output", .{});
}
- const inputs = try arena.alloc(*zir.Inst, full.inputs.len);
+ const inputs = try arena.alloc([]const u8, full.inputs.len);
const args = try arena.alloc(*zir.Inst, full.inputs.len);
const src = token_starts[full.ast.asm_token];
@@ -3010,15 +3208,16 @@ fn assembly(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) Inne
for (full.inputs) |input, i| {
// TODO semantically analyze constraints
- inputs[i] = try expr(mod, scope, str_type_rl, input.constraint);
- args[i] = try expr(mod, scope, .none, input.expr);
+ const constraint_token = main_tokens[input] + 2;
+ inputs[i] = try parseStringLiteral(mod, scope, constraint_token);
+ args[i] = try expr(mod, scope, .none, node_datas[input].lhs);
}
const return_type = try addZIRInstConst(mod, scope, src, .{
.ty = Type.initTag(.type),
.val = Value.initTag(.void_type),
});
- const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.@"asm", .{
+ const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.Asm, .{
.asm_source = try expr(mod, scope, str_type_rl, full.ast.template),
.return_type = return_type,
}, .{
@@ -3185,8 +3384,9 @@ fn builtinCall(
params: []const ast.Node.Index,
) InnerError!*zir.Inst {
const tree = scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+
const builtin_token = main_tokens[call];
const builtin_name = tree.tokenSlice(builtin_token);
@@ -3200,11 +3400,13 @@ fn builtinCall(
builtin_name,
});
};
- if (info.param_count != params.len) {
- const s = if (params.len == 1) "" else "s";
- return mod.failTok(scope, builtin_token, "expected {d} parameter{s}, found {d}", .{
- expected, s, found,
- });
+ if (info.param_count) |expected| {
+ if (expected != params.len) {
+ const s = if (expected == 1) "" else "s";
+ return mod.failTok(scope, builtin_token, "expected {d} parameter{s}, found {d}", .{
+ expected, s, params.len,
+ });
+ }
}
const src = token_starts[builtin_token];
@@ -3237,7 +3439,7 @@ fn builtinCall(
},
.compile_error => {
const target = try expr(mod, scope, .none, params[0]);
- const result = addZIRUnOp(mod, scope, src, .compile_error, target);
+ const result = try addZIRUnOp(mod, scope, src, .compile_error, target);
return rvalue(mod, scope, rl, result);
},
.set_eval_branch_quota => {
@@ -3386,8 +3588,9 @@ fn callExpr(
}
const tree = scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
+ const token_starts = tree.tokens.items(.start);
+
const lhs = try expr(mod, scope, .none, call.ast.fn_expr);
const args = try scope.getGenZIR().arena.alloc(*zir.Inst, call.ast.params.len);
@@ -3446,23 +3649,26 @@ fn getSimplePrimitiveValue(name: []const u8) ?TypedValue {
return null;
}
-fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
+fn nodeMayNeedMemoryLocation(scope: *Scope, start_node: ast.Node.Index) bool {
+ const tree = scope.tree();
+ const node_tags = tree.nodes.items(.tag);
+ const node_datas = tree.nodes.items(.data);
+ const main_tokens = tree.nodes.items(.main_token);
+ const token_tags = tree.tokens.items(.tag);
+
var node = start_node;
while (true) {
- switch (node.tag) {
- .Root,
+ switch (node_tags[node]) {
+ .root,
.@"usingnamespace",
.test_decl,
- .doc_comment,
.switch_case,
- .switch_else,
- .Else,
- .Payload,
- .PointerPayload,
- .PointerIndexPayload,
- .ContainerField,
- .ErrorTag,
- .FieldInitializer,
+ .switch_case_one,
+ .container_field_init,
+ .container_field_align,
+ .container_field,
+ .asm_output,
+ .asm_input,
=> unreachable,
.@"return",
@@ -3470,8 +3676,12 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
.@"continue",
.bit_not,
.bool_not,
- .var_decl,
+ .global_var_decl,
+ .local_var_decl,
+ .simple_var_decl,
+ .aligned_var_decl,
.@"defer",
+ .@"errdefer",
.address_of,
.optional_type,
.negation,
@@ -3479,27 +3689,46 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
.@"resume",
.array_type,
.array_type_sentinel,
- .PtrType,
- .slice_type,
+ .ptr_type_aligned,
+ .ptr_type_sentinel,
+ .ptr_type,
+ .ptr_type_bit_range,
.@"suspend",
.@"anytype",
- .error_type,
- .FnProto,
+ .fn_proto_simple,
+ .fn_proto_multi,
+ .fn_proto_one,
+ .fn_proto,
+ .fn_decl,
.anyframe_type,
+ .anyframe_literal,
.integer_literal,
.float_literal,
.enum_literal,
.string_literal,
- .MultilineStringLiteral,
+ .multiline_string_literal,
.char_literal,
- .bool_literal,
+ .true_literal,
+ .false_literal,
.null_literal,
.undefined_literal,
- .@"unreachable",
+ .unreachable_literal,
.identifier,
.error_set_decl,
- .ContainerDecl,
+ .container_decl,
+ .container_decl_comma,
+ .container_decl_two,
+ .container_decl_two_comma,
+ .container_decl_arg,
+ .container_decl_arg_comma,
+ .tagged_union,
+ .tagged_union_comma,
+ .tagged_union_two,
+ .tagged_union_two_comma,
+ .tagged_union_enum_tag,
+ .tagged_union_enum_tag_comma,
.@"asm",
+ .asm_simple,
.add,
.add_wrap,
.array_cat,
@@ -3537,14 +3766,16 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
.mod,
.mul,
.mul_wrap,
- .range,
- .period,
+ .switch_range,
+ .field_access,
.sub,
.sub_wrap,
.slice,
+ .slice_open,
+ .slice_sentinel,
.deref,
.array_access,
- .block,
+ .error_value,
.while_simple, // This variant cannot have an else expression.
.while_cont, // This variant cannot have an else expression.
.for_simple, // This variant cannot have an else expression.
@@ -3558,18 +3789,30 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
.@"comptime",
.@"nosuspend",
.unwrap_optional,
- => node = datas[node].lhs,
+ => node = node_datas[node].lhs,
// Forward the question to the RHS sub-expression.
.@"catch",
.@"orelse",
- => node = datas[node].rhs,
+ => node = node_datas[node].rhs,
// True because these are exactly the expressions we need memory locations for.
- .ArrayInitializer,
- .ArrayInitializerDot,
- .StructInitializer,
- .StructInitializerDot,
+ .array_init_one,
+ .array_init_one_comma,
+ .array_init_dot_two,
+ .array_init_dot_two_comma,
+ .array_init_dot,
+ .array_init_dot_comma,
+ .array_init,
+ .array_init_comma,
+ .struct_init_one,
+ .struct_init_one_comma,
+ .struct_init_dot_two,
+ .struct_init_dot_two_comma,
+ .struct_init_dot,
+ .struct_init_dot_comma,
+ .struct_init,
+ .struct_init_comma,
=> return true,
// True because depending on comptime conditions, sub-expressions
@@ -3578,6 +3821,7 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
.@"if", // This variant always has an else expression.
.@"for", // This variant always has an else expression.
.@"switch",
+ .switch_comma,
.call_one,
.call_one_comma,
.async_call_one,
@@ -3588,10 +3832,10 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
.async_call_comma,
=> return true,
- block_two,
- block_two_semicolon,
- block,
- block_semicolon,
+ .block_two,
+ .block_two_semicolon,
+ .block,
+ .block_semicolon,
=> {
const lbrace = main_tokens[node];
if (token_tags[lbrace - 1] == .colon) {
@@ -3603,7 +3847,11 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
}
},
- .builtin_call => {
+ .builtin_call,
+ .builtin_call_comma,
+ .builtin_call_two,
+ .builtin_call_two_comma,
+ => {
const builtin_token = main_tokens[node];
const builtin_name = tree.tokenSlice(builtin_token);
// If the builtin is an invalid name, we don't cause an error here; instead
@@ -3661,7 +3909,6 @@ fn rvalueVoid(
result: void,
) InnerError!*zir.Inst {
const tree = scope.tree();
- const node_datas = tree.nodes.items(.data);
const main_tokens = tree.nodes.items(.main_token);
const src = tree.tokens.items(.start)[tree.firstToken(node)];
const void_inst = try addZIRInstConst(mod, scope, src, .{
@@ -3765,7 +4012,7 @@ pub fn addZirInstT(
src: usize,
comptime T: type,
tag: zir.Inst.Tag,
- positionals: std.meta.fieldInfo(tag.Type(), .positionals).field_type,
+ positionals: std.meta.fieldInfo(T, .positionals).field_type,
) !*T {
const gen_zir = scope.getGenZIR();
try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1);
diff --git a/src/zir.zig b/src/zir.zig
index 9a3c080760..ee0fd3dc3d 100644
--- a/src/zir.zig
+++ b/src/zir.zig
@@ -863,8 +863,8 @@ pub const Inst = struct {
kw_args: struct {
@"volatile": bool = false,
output: ?*Inst = null,
- inputs: []*Inst = &[0]*Inst{},
- clobbers: []*Inst = &[0]*Inst{},
+ inputs: []const []const u8 = &.{},
+ clobbers: []const []const u8 = &.{},
args: []*Inst = &[0]*Inst{},
},
};
@@ -1192,16 +1192,9 @@ pub const Inst = struct {
},
kw_args: struct {
init_inst: ?*Inst = null,
- init_kind: InitKind = .none,
+ has_enum_token: bool,
layout: std.builtin.TypeInfo.ContainerLayout = .Auto,
},
-
- // TODO error: values of type '(enum literal)' must be comptime known
- pub const InitKind = enum {
- enum_type,
- tag_type,
- none,
- };
};
pub const SwitchBr = struct {
@@ -1413,6 +1406,7 @@ const Writer = struct {
}
switch (@TypeOf(param)) {
*Inst => return self.writeInstParamToStream(stream, param),
+ ?*Inst => return self.writeInstParamToStream(stream, param.?),
[]*Inst => {
try stream.writeByte('[');
for (param) |inst, i| {
@@ -1480,7 +1474,7 @@ const Writer = struct {
const name = self.loop_table.get(param).?;
return stream.print("\"{}\"", .{std.zig.fmtEscapes(name)});
},
- [][]const u8 => {
+ [][]const u8, []const []const u8 => {
try stream.writeByte('[');
for (param) |str, i| {
if (i != 0) {
diff --git a/src/zir_sema.zig b/src/zir_sema.zig
index 83d7113c9c..b20e78d448 100644
--- a/src/zir_sema.zig
+++ b/src/zir_sema.zig
@@ -2023,19 +2023,21 @@ fn zirDeref(mod: *Module, scope: *Scope, deref: *zir.Inst.UnOp) InnerError!*Inst
fn zirAsm(mod: *Module, scope: *Scope, assembly: *zir.Inst.Asm) InnerError!*Inst {
const tracy = trace(@src());
defer tracy.end();
+
const return_type = try resolveType(mod, scope, assembly.positionals.return_type);
const asm_source = try resolveConstString(mod, scope, assembly.positionals.asm_source);
const output = if (assembly.kw_args.output) |o| try resolveConstString(mod, scope, o) else null;
- const inputs = try scope.arena().alloc([]const u8, assembly.kw_args.inputs.len);
- const clobbers = try scope.arena().alloc([]const u8, assembly.kw_args.clobbers.len);
- const args = try scope.arena().alloc(*Inst, assembly.kw_args.args.len);
+ const arena = scope.arena();
+ const inputs = try arena.alloc([]const u8, assembly.kw_args.inputs.len);
+ const clobbers = try arena.alloc([]const u8, assembly.kw_args.clobbers.len);
+ const args = try arena.alloc(*Inst, assembly.kw_args.args.len);
for (inputs) |*elem, i| {
- elem.* = try resolveConstString(mod, scope, assembly.kw_args.inputs[i]);
+ elem.* = try arena.dupe(u8, assembly.kw_args.inputs[i]);
}
for (clobbers) |*elem, i| {
- elem.* = try resolveConstString(mod, scope, assembly.kw_args.clobbers[i]);
+ elem.* = try arena.dupe(u8, assembly.kw_args.clobbers[i]);
}
for (args) |*elem, i| {
const arg = try resolveInst(mod, scope, assembly.kw_args.args[i]);