authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-03 00:42:00-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-03 00:42:00-05:00
log1d77f8db289e6eefce827fe37d27e72b68362943
tree62bcadb5abcf45076583c362cb68e254067020f0
parent6bfaf262d5a1d18482a813c7022ffb03a18f52a8
parent0ea50b3157f00ab56b2752dfa8c70edb4bce2af7

Merge branch 'master' into llvm6


14 files changed, 647 insertions(+), 1385 deletions(-)

CMakeLists.txt+1
......@@ -605,6 +605,7 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/index.zig" DESTINATION "${ZIG_
605605install(FILES "${CMAKE_SOURCE_DIR}/std/os/windows/util.zig" DESTINATION "${ZIG_STD_DEST}/os/windows")
606606install(FILES "${CMAKE_SOURCE_DIR}/std/rand.zig" DESTINATION "${ZIG_STD_DEST}")
607607install(FILES "${CMAKE_SOURCE_DIR}/std/sort.zig" DESTINATION "${ZIG_STD_DEST}")
608install(FILES "${CMAKE_SOURCE_DIR}/std/unicode.zig" DESTINATION "${ZIG_STD_DEST}")
608609install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap.zig" DESTINATION "${ZIG_STD_DEST}/special")
609610install(FILES "${CMAKE_SOURCE_DIR}/std/special/bootstrap_lib.zig" DESTINATION "${ZIG_STD_DEST}/special")
610611install(FILES "${CMAKE_SOURCE_DIR}/std/special/build_file_template.zig" DESTINATION "${ZIG_STD_DEST}/special")
build.zig+1
......@@ -276,6 +276,7 @@ pub fn installStdLib(b: &Builder) {
276276 "os/windows/util.zig",
277277 "rand.zig",
278278 "sort.zig",
279 "unicode.zig",
279280 "special/bootstrap.zig",
280281 "special/bootstrap_lib.zig",
281282 "special/build_file_template.zig",
doc/langref.html.in+1-1
......@@ -298,7 +298,7 @@ pub fn main() -&gt; %void {
298298 <li>Ascii control characters, except for U+000a (LF): U+0000 - U+0009, U+000b - U+0001f, U+007f. (Note that Windows line endings (CRLF) are not allowed, and hard tabs are not allowed.)</li>
299299 <li>Non-Ascii Unicode line endings: U+0085 (NEL), U+2028 (LS), U+2029 (PS).</li>
300300 </ul>
301 <p>The codepoint U+000a (LF) (which is encoded as the single-byte value 0x0a) is the line terminator character. This character always terminates a line of zig source code. A non-empty zig source must end with the line terminator character.</p>
301 <p>The codepoint U+000a (LF) (which is encoded as the single-byte value 0x0a) is the line terminator character. This character always terminates a line of zig source code (except possbly the last line of the file).</p>
302302 <p>For some discussion on the rationale behind these design decisions, see <a href="https://github.com/zig-lang/zig/issues/663">issue #663</a></p>
303303 <h2 id="values">Values</h2>
304304 <pre><code class="zig">const warn = @import("std").debug.warn;
src-self-hosted/module.zig+4-1
......@@ -213,11 +213,14 @@ pub const Module = struct {
213213 };
214214 %defer self.allocator.free(root_src_real_path);
215215
216 const source_code = io.readFileAlloc(root_src_real_path, self.allocator) %% |err| {
216 const source_code = io.readFileAllocExtra(root_src_real_path, self.allocator, 3) %% |err| {
217217 %return printError("unable to open '{}': {}", root_src_real_path, err);
218218 return err;
219219 };
220220 %defer self.allocator.free(source_code);
221 source_code[source_code.len - 3] = '\n';
222 source_code[source_code.len - 2] = '\n';
223 source_code[source_code.len - 1] = '\n';
221224
222225 warn("====input:====\n");
223226
src-self-hosted/parser.zig+7-1
......@@ -1086,7 +1086,13 @@ pub const Parser = struct {
10861086var fixed_buffer_mem: [100 * 1024]u8 = undefined;
10871087
10881088fn testParse(source: []const u8, allocator: &mem.Allocator) -> %[]u8 {
1089 var tokenizer = Tokenizer.init(source);
1089 var padded_source: [0x100]u8 = undefined;
1090 std.mem.copy(u8, padded_source[0..source.len], source);
1091 padded_source[source.len + 0] = '\n';
1092 padded_source[source.len + 1] = '\n';
1093 padded_source[source.len + 2] = '\n';
1094
1095 var tokenizer = Tokenizer.init(padded_source[0..source.len + 3]);
10901096 var parser = Parser.init(&tokenizer, allocator, "(memory buffer)");
10911097 defer parser.deinit();
10921098
src-self-hosted/tokenizer.zig+66-138
......@@ -70,7 +70,6 @@ pub const Token = struct {
7070 Identifier,
7171 StringLiteral: StrLitKind,
7272 Eof,
73 NoEolAtEof,
7473 Builtin,
7574 Bang,
7675 Equal,
......@@ -140,7 +139,6 @@ pub const Token = struct {
140139pub const Tokenizer = struct {
141140 buffer: []const u8,
142141 index: usize,
143 actual_file_end: usize,
144142 pending_invalid_token: ?Token,
145143
146144 pub const Location = struct {
......@@ -179,17 +177,15 @@ pub const Tokenizer = struct {
179177 std.debug.warn("{} \"{}\"\n", @tagName(token.id), self.buffer[token.start..token.end]);
180178 }
181179
180 /// buffer must end with "\n\n\n". This is so that attempting to decode
181 /// a the 3 trailing bytes of a 4-byte utf8 sequence is never a buffer overflow.
182182 pub fn init(buffer: []const u8) -> Tokenizer {
183 var source_len = buffer.len;
184 while (source_len > 0) : (source_len -= 1) {
185 if (buffer[source_len - 1] == '\n') break;
186 // last line is incomplete, so skip it, and give an error when we get there.
187 }
188
183 std.debug.assert(buffer[buffer.len - 1] == '\n');
184 std.debug.assert(buffer[buffer.len - 2] == '\n');
185 std.debug.assert(buffer[buffer.len - 3] == '\n');
189186 return Tokenizer {
190 .buffer = buffer[0..source_len],
187 .buffer = buffer,
191188 .index = 0,
192 .actual_file_end = buffer.len,
193189 .pending_invalid_token = null,
194190 };
195191 }
......@@ -512,17 +508,14 @@ pub const Tokenizer = struct {
512508 }
513509 }
514510 result.end = self.index;
511
515512 if (result.id == Token.Id.Eof) {
516513 if (self.pending_invalid_token) |token| {
517514 self.pending_invalid_token = null;
518515 return token;
519516 }
520 if (self.actual_file_end != self.buffer.len) {
521 // instead of an Eof, give an error token
522 result.id = Token.Id.NoEolAtEof;
523 result.end = self.actual_file_end;
524 }
525517 }
518
526519 return result;
527520 }
528521
......@@ -553,161 +546,96 @@ pub const Tokenizer = struct {
553546 return 0;
554547 } else {
555548 // check utf8-encoded character.
556 // remember that the last byte in the buffer is guaranteed to be '\n',
557 // which means we really don't need to do bounds checks here,
558 // as long as we check one byte at a time for being a continuation byte.
559 var value: u32 = undefined;
560 var length: u3 = undefined;
561 if (c0 & 0b11100000 == 0b11000000) {value = c0 & 0b00011111; length = 2;}
562 else if (c0 & 0b11110000 == 0b11100000) {value = c0 & 0b00001111; length = 3;}
563 else if (c0 & 0b11111000 == 0b11110000) {value = c0 & 0b00000111; length = 4;}
564 else return 1; // unexpected continuation or too many leading 1's
565
566 const c1 = self.buffer[self.index + 1];
567 if (c1 & 0b11000000 != 0b10000000) return 1; // expected continuation
568 value <<= 6;
569 value |= c1 & 0b00111111;
570 if (length == 2) {
571 if (value < 0x80) return length; // overlong
572 if (value == 0x85) return length; // U+0085 (NEL)
573 self.index += length - 1;
574 return 0;
575 }
576 const c2 = self.buffer[self.index + 2];
577 if (c2 & 0b11000000 != 0b10000000) return 2; // expected continuation
578 value <<= 6;
579 value |= c2 & 0b00111111;
580 if (length == 3) {
581 if (value < 0x800) return length; // overlong
582 if (value == 0x2028) return length; // U+2028 (LS)
583 if (value == 0x2029) return length; // U+2029 (PS)
584 if (0xd800 <= value and value <= 0xdfff) return length; // surrogate halves not allowed in utf8
585 self.index += length - 1;
586 return 0;
587 }
588 const c3 = self.buffer[self.index + 3];
589 if (c3 & 0b11000000 != 0b10000000) return 3; // expected continuation
590 value <<= 6;
591 value |= c3 & 0b00111111;
592 if (length == 4) {
593 if (value < 0x10000) return length; // overlong
594 if (value > 0x10FFFF) return length; // out of bounds
595 self.index += length - 1;
596 return 0;
549 const length = std.unicode.utf8ByteSequenceLength(c0) %% return 1;
550 // the last 3 bytes in the buffer are guaranteed to be '\n',
551 // which means we don't need to do any bounds checking here.
552 const bytes = self.buffer[self.index..self.index + length];
553 switch (length) {
554 2 => {
555 const value = std.unicode.utf8Decode2(bytes) %% return length;
556 if (value == 0x85) return length; // U+0085 (NEL)
557 },
558 3 => {
559 const value = std.unicode.utf8Decode3(bytes) %% return length;
560 if (value == 0x2028) return length; // U+2028 (LS)
561 if (value == 0x2029) return length; // U+2029 (PS)
562 },
563 4 => {
564 _ = std.unicode.utf8Decode4(bytes) %% return length;
565 },
566 else => unreachable,
597567 }
598 unreachable;
568 self.index += length - 1;
569 return 0;
599570 }
600571 }
601572};
602573
603574
604575
605test "tokenizer - source must end with eol" {
606 testTokenizeWithEol("", []Token.Id {
607 }, true);
608 testTokenizeWithEol("no newline", []Token.Id {
609 }, false);
610 testTokenizeWithEol("test\n", []Token.Id {
611 Token.Id.Keyword_test,
612 }, true);
613 testTokenizeWithEol("test\nno newline", []Token.Id {
576test "tokenizer" {
577 testTokenize("test", []Token.Id {
614578 Token.Id.Keyword_test,
615 }, false);
579 });
616580}
617581
618582test "tokenizer - invalid token characters" {
619 testTokenize("#\n", []Token.Id{Token.Id.Invalid});
620 testTokenize("`\n", []Token.Id{Token.Id.Invalid});
583 testTokenize("#", []Token.Id{Token.Id.Invalid});
584 testTokenize("`", []Token.Id{Token.Id.Invalid});
621585}
622586
623587test "tokenizer - invalid literal/comment characters" {
624 testTokenize("\"\x00\"\n", []Token.Id {
588 testTokenize("\"\x00\"", []Token.Id {
625589 Token.Id { .StringLiteral = Token.StrLitKind.Normal },
626590 Token.Id.Invalid,
627591 });
628 testTokenize("//\x00\n", []Token.Id {
592 testTokenize("//\x00", []Token.Id {
629593 Token.Id.Invalid,
630594 });
631 testTokenize("//\x1f\n", []Token.Id {
595 testTokenize("//\x1f", []Token.Id {
632596 Token.Id.Invalid,
633597 });
634 testTokenize("//\x7f\n", []Token.Id {
598 testTokenize("//\x7f", []Token.Id {
635599 Token.Id.Invalid,
636600 });
637601}
638602
639test "tokenizer - valid unicode" {
640 testTokenize("//\xc2\x80\n", []Token.Id{});
641 testTokenize("//\xdf\xbf\n", []Token.Id{});
642 testTokenize("//\xe0\xa0\x80\n", []Token.Id{});
643 testTokenize("//\xe1\x80\x80\n", []Token.Id{});
644 testTokenize("//\xef\xbf\xbf\n", []Token.Id{});
645 testTokenize("//\xf0\x90\x80\x80\n", []Token.Id{});
646 testTokenize("//\xf1\x80\x80\x80\n", []Token.Id{});
647 testTokenize("//\xf3\xbf\xbf\xbf\n", []Token.Id{});
648 testTokenize("//\xf4\x8f\xbf\xbf\n", []Token.Id{});
649}
650
651test "tokenizer - invalid unicode continuation bytes" {
652 // unexpected continuation
653 testTokenize("//\x80\n", []Token.Id{Token.Id.Invalid});
654 testTokenize("//\xbf\n", []Token.Id{Token.Id.Invalid});
655 // too many leading 1's
656 testTokenize("//\xf8\n", []Token.Id{Token.Id.Invalid});
657 testTokenize("//\xff\n", []Token.Id{Token.Id.Invalid});
658 // expected continuation for 2 byte sequences
659 testTokenize("//\xc2\x00\n", []Token.Id{Token.Id.Invalid});
660 testTokenize("//\xc2\xc0\n", []Token.Id{Token.Id.Invalid});
661 // expected continuation for 3 byte sequences
662 testTokenize("//\xe0\x00\n", []Token.Id{Token.Id.Invalid});
663 testTokenize("//\xe0\xc0\n", []Token.Id{Token.Id.Invalid});
664 testTokenize("//\xe0\xa0\n", []Token.Id{Token.Id.Invalid});
665 testTokenize("//\xe0\xa0\x00\n", []Token.Id{Token.Id.Invalid});
666 testTokenize("//\xe0\xa0\xc0\n", []Token.Id{Token.Id.Invalid});
667 // expected continuation for 4 byte sequences
668 testTokenize("//\xf0\x00\n", []Token.Id{Token.Id.Invalid});
669 testTokenize("//\xf0\xc0\n", []Token.Id{Token.Id.Invalid});
670 testTokenize("//\xf0\x90\x00\n", []Token.Id{Token.Id.Invalid});
671 testTokenize("//\xf0\x90\xc0\n", []Token.Id{Token.Id.Invalid});
672 testTokenize("//\xf0\x90\x80\x00\n", []Token.Id{Token.Id.Invalid});
673 testTokenize("//\xf0\x90\x80\xc0\n", []Token.Id{Token.Id.Invalid});
603test "tokenizer - utf8" {
604 testTokenize("//\xc2\x80", []Token.Id{});
605 testTokenize("//\xf4\x8f\xbf\xbf", []Token.Id{});
674606}
675607
676test "tokenizer - overlong utf8 codepoint" {
677 testTokenize("//\xc0\x80\n", []Token.Id{Token.Id.Invalid});
678 testTokenize("//\xc1\xbf\n", []Token.Id{Token.Id.Invalid});
679 testTokenize("//\xe0\x80\x80\n", []Token.Id{Token.Id.Invalid});
680 testTokenize("//\xe0\x9f\xbf\n", []Token.Id{Token.Id.Invalid});
681 testTokenize("//\xf0\x80\x80\x80\n", []Token.Id{Token.Id.Invalid});
682 testTokenize("//\xf0\x8f\xbf\xbf\n", []Token.Id{Token.Id.Invalid});
608test "tokenizer - invalid utf8" {
609 testTokenize("//\x80", []Token.Id{Token.Id.Invalid});
610 testTokenize("//\xbf", []Token.Id{Token.Id.Invalid});
611 testTokenize("//\xf8", []Token.Id{Token.Id.Invalid});
612 testTokenize("//\xff", []Token.Id{Token.Id.Invalid});
613 testTokenize("//\xc2\xc0", []Token.Id{Token.Id.Invalid});
614 testTokenize("//\xe0", []Token.Id{Token.Id.Invalid});
615 testTokenize("//\xf0", []Token.Id{Token.Id.Invalid});
616 testTokenize("//\xf0\x90\x80\xc0", []Token.Id{Token.Id.Invalid});
683617}
684618
685test "tokenizer - misc invalid utf8" {
686 // codepoint out of bounds
687 testTokenize("//\xf4\x90\x80\x80\n", []Token.Id{Token.Id.Invalid});
688 testTokenize("//\xf7\xbf\xbf\xbf\n", []Token.Id{Token.Id.Invalid});
619test "tokenizer - illegal unicode codepoints" {
689620 // unicode newline characters.U+0085, U+2028, U+2029
690 testTokenize("//\xc2\x84\n", []Token.Id{});
691 testTokenize("//\xc2\x85\n", []Token.Id{Token.Id.Invalid});
692 testTokenize("//\xc2\x86\n", []Token.Id{});
693 testTokenize("//\xe2\x80\xa7\n", []Token.Id{});
694 testTokenize("//\xe2\x80\xa8\n", []Token.Id{Token.Id.Invalid});
695 testTokenize("//\xe2\x80\xa9\n", []Token.Id{Token.Id.Invalid});
696 testTokenize("//\xe2\x80\xaa\n", []Token.Id{});
697 // surrogate halves
698 testTokenize("//\xed\x9f\x80\n", []Token.Id{});
699 testTokenize("//\xed\xa0\x80\n", []Token.Id{Token.Id.Invalid});
700 testTokenize("//\xed\xbf\xbf\n", []Token.Id{Token.Id.Invalid});
701 testTokenize("//\xee\x80\x80\n", []Token.Id{});
702 // surrogate halves are invalid, even in surrogate pairs
703 testTokenize("//\xed\xa0\xad\xed\xb2\xa9\n", []Token.Id{Token.Id.Invalid});
621 testTokenize("//\xc2\x84", []Token.Id{});
622 testTokenize("//\xc2\x85", []Token.Id{Token.Id.Invalid});
623 testTokenize("//\xc2\x86", []Token.Id{});
624 testTokenize("//\xe2\x80\xa7", []Token.Id{});
625 testTokenize("//\xe2\x80\xa8", []Token.Id{Token.Id.Invalid});
626 testTokenize("//\xe2\x80\xa9", []Token.Id{Token.Id.Invalid});
627 testTokenize("//\xe2\x80\xaa", []Token.Id{});
704628}
705629
706630fn testTokenize(source: []const u8, expected_tokens: []const Token.Id) {
707 testTokenizeWithEol(source, expected_tokens, true);
708}
709fn testTokenizeWithEol(source: []const u8, expected_tokens: []const Token.Id, expected_eol_at_eof: bool) {
710 var tokenizer = Tokenizer.init(source);
631 // (test authors, just make this bigger if you need it)
632 var padded_source: [0x100]u8 = undefined;
633 std.mem.copy(u8, padded_source[0..source.len], source);
634 padded_source[source.len + 0] = '\n';
635 padded_source[source.len + 1] = '\n';
636 padded_source[source.len + 2] = '\n';
637
638 var tokenizer = Tokenizer.init(padded_source[0..source.len + 3]);
711639 for (expected_tokens) |expected_token_id| {
712640 const token = tokenizer.next();
713641 std.debug.assert(@TagType(Token.Id)(token.id) == @TagType(Token.Id)(expected_token_id));
......@@ -718,5 +646,5 @@ fn testTokenizeWithEol(source: []const u8, expected_tokens: []const Token.Id, ex
718646 else => {},
719647 }
720648 }
721 std.debug.assert(tokenizer.next().id == if (expected_eol_at_eof) Token.Id.Eof else Token.Id.NoEolAtEof);
649 std.debug.assert(tokenizer.next().id == Token.Id.Eof);
722650}
src/ir.cpp+267-1233
......@@ -31,8 +31,7 @@ struct IrAnalyze {
3131 IrBuilder old_irb;
3232 IrBuilder new_irb;
3333 IrExecContext exec_context;
34 ZigList<IrBasicBlock *> old_bb_queue;
35 size_t block_queue_index;
34 size_t old_bb_index;
3635 size_t instruction_index;
3736 TypeTableEntry *explicit_return_type;
3837 ZigList<IrInstruction *> implicit_return_type_list;
......@@ -159,12 +158,6 @@ static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const c
159158 return result;
160159}
161160
162static IrBasicBlock *ir_build_basic_block(IrBuilder *irb, Scope *scope, const char *name_hint) {
163 IrBasicBlock *result = ir_create_basic_block(irb, scope, name_hint);
164 irb->exec->basic_block_list.append(result);
165 return result;
166}
167
168161static IrBasicBlock *ir_build_bb_from(IrBuilder *irb, IrBasicBlock *other_bb) {
169162 IrBasicBlock *new_bb = ir_create_basic_block(irb, other_bb->scope, other_bb->name_hint);
170163 ir_link_new_bb(new_bb, other_bb);
......@@ -2258,1031 +2251,58 @@ static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *so
22582251 return &instruction->base;
22592252}
22602253
2261static IrInstruction *ir_build_set_eval_branch_quota(IrBuilder *irb, Scope *scope, AstNode *source_node,
2262 IrInstruction *new_quota)
2263{
2264 IrInstructionSetEvalBranchQuota *instruction = ir_build_instruction<IrInstructionSetEvalBranchQuota>(irb, scope, source_node);
2265 instruction->new_quota = new_quota;
2266
2267 ir_ref_instruction(new_quota, irb->current_basic_block);
2268
2269 return &instruction->base;
2270}
2271
2272static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
2273 IrInstruction *align_bytes, IrInstruction *target)
2274{
2275 IrInstructionAlignCast *instruction = ir_build_instruction<IrInstructionAlignCast>(irb, scope, source_node);
2276 instruction->align_bytes = align_bytes;
2277 instruction->target = target;
2278
2279 if (align_bytes) ir_ref_instruction(align_bytes, irb->current_basic_block);
2280 ir_ref_instruction(target, irb->current_basic_block);
2281
2282 return &instruction->base;
2283}
2284
2285static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) {
2286 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node);
2287
2288 return &instruction->base;
2289}
2290
2291static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, AstNode *source_node,
2292 IrInstruction *align_bytes)
2293{
2294 IrInstructionSetAlignStack *instruction = ir_build_instruction<IrInstructionSetAlignStack>(irb, scope, source_node);
2295 instruction->align_bytes = align_bytes;
2296
2297 ir_ref_instruction(align_bytes, irb->current_basic_block);
2298
2299 return &instruction->base;
2300}
2301
2302static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
2303 IrInstruction *fn_type, IrInstruction *arg_index)
2304{
2305 IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node);
2306 instruction->fn_type = fn_type;
2307 instruction->arg_index = arg_index;
2308
2309 ir_ref_instruction(fn_type, irb->current_basic_block);
2310 ir_ref_instruction(arg_index, irb->current_basic_block);
2311
2312 return &instruction->base;
2313}
2314
2315static IrInstruction *ir_instruction_br_get_dep(IrInstructionBr *instruction, size_t index) {
2316 return nullptr;
2317}
2318
2319static IrInstruction *ir_instruction_condbr_get_dep(IrInstructionCondBr *instruction, size_t index) {
2320 switch (index) {
2321 case 0: return instruction->condition;
2322 default: return nullptr;
2323 }
2324}
2325
2326static IrInstruction *ir_instruction_switchbr_get_dep(IrInstructionSwitchBr *instruction, size_t index) {
2327 switch (index) {
2328 case 0: return instruction->target_value;
2329 }
2330 size_t case_index = index - 2;
2331 if (case_index < instruction->case_count) return instruction->cases[case_index].value;
2332 return nullptr;
2333}
2334
2335static IrInstruction *ir_instruction_switchvar_get_dep(IrInstructionSwitchVar *instruction, size_t index) {
2336 switch (index) {
2337 case 0: return instruction->target_value_ptr;
2338 case 1: return instruction->prong_value;
2339 default: return nullptr;
2340 }
2341}
2342
2343static IrInstruction *ir_instruction_switchtarget_get_dep(IrInstructionSwitchTarget *instruction, size_t index) {
2344 switch (index) {
2345 case 0: return instruction->target_value_ptr;
2346 default: return nullptr;
2347 }
2348}
2349
2350static IrInstruction *ir_instruction_phi_get_dep(IrInstructionPhi *instruction, size_t index) {
2351 if (index < instruction->incoming_count) return instruction->incoming_values[index];
2352 return nullptr;
2353}
2354
2355static IrInstruction *ir_instruction_unop_get_dep(IrInstructionUnOp *instruction, size_t index) {
2356 switch (index) {
2357 case 0: return instruction->value;
2358 default: return nullptr;
2359 }
2360}
2361
2362static IrInstruction *ir_instruction_binop_get_dep(IrInstructionBinOp *instruction, size_t index) {
2363 switch (index) {
2364 case 0: return instruction->op1;
2365 case 1: return instruction->op2;
2366 default: return nullptr;
2367 }
2368}
2369
2370static IrInstruction *ir_instruction_declvar_get_dep(IrInstructionDeclVar *instruction, size_t index) {
2371 if (index == 0) return instruction->init_value;
2372 index -= 1;
2373
2374 if (instruction->align_value != nullptr) {
2375 if (index == 0) return instruction->align_value;
2376 index -= 1;
2377 }
2378
2379 if (instruction->var_type != nullptr) {
2380 if (index == 0) return instruction->var_type;
2381 index -= 1;
2382 }
2383
2384 return nullptr;
2385}
2386
2387static IrInstruction *ir_instruction_export_get_dep(IrInstructionExport *instruction, size_t index) {
2388 if (index < 1) return instruction->name;
2389 index -= 1;
2390
2391 if (index < 1) return instruction->target;
2392 index -= 1;
2393
2394 if (instruction->linkage != nullptr) {
2395 if (index < 1) return instruction->linkage;
2396 index -= 1;
2397 }
2398
2399 return nullptr;
2400}
2401
2402static IrInstruction *ir_instruction_loadptr_get_dep(IrInstructionLoadPtr *instruction, size_t index) {
2403 switch (index) {
2404 case 0: return instruction->ptr;
2405 default: return nullptr;
2406 }
2407}
2408
2409static IrInstruction *ir_instruction_storeptr_get_dep(IrInstructionStorePtr *instruction, size_t index) {
2410 switch (index) {
2411 case 0: return instruction->ptr;
2412 case 1: return instruction->value;
2413 default: return nullptr;
2414 }
2415}
2416
2417static IrInstruction *ir_instruction_fieldptr_get_dep(IrInstructionFieldPtr *instruction, size_t index) {
2418 switch (index) {
2419 case 0: return instruction->container_ptr;
2420 default: return nullptr;
2421 }
2422}
2423
2424static IrInstruction *ir_instruction_structfieldptr_get_dep(IrInstructionStructFieldPtr *instruction, size_t index) {
2425 switch (index) {
2426 case 0: return instruction->struct_ptr;
2427 default: return nullptr;
2428 }
2429}
2430
2431static IrInstruction *ir_instruction_unionfieldptr_get_dep(IrInstructionUnionFieldPtr *instruction, size_t index) {
2432 switch (index) {
2433 case 0: return instruction->union_ptr;
2434 default: return nullptr;
2435 }
2436}
2437
2438static IrInstruction *ir_instruction_elemptr_get_dep(IrInstructionElemPtr *instruction, size_t index) {
2439 switch (index) {
2440 case 0: return instruction->array_ptr;
2441 case 1: return instruction->elem_index;
2442 default: return nullptr;
2443 }
2444}
2445
2446static IrInstruction *ir_instruction_varptr_get_dep(IrInstructionVarPtr *instruction, size_t index) {
2447 switch (index) {
2448 case 0: return instruction->var->decl_instruction; // can be null
2449 default: return nullptr;
2450 }
2451}
2452
2453static IrInstruction *ir_instruction_call_get_dep(IrInstructionCall *instruction, size_t index) {
2454 if (index == 0) return instruction->fn_ref;
2455 size_t arg_index = index - 1;
2456 if (arg_index < instruction->arg_count) return instruction->args[arg_index];
2457 return nullptr;
2458}
2459
2460static IrInstruction *ir_instruction_const_get_dep(IrInstructionConst *instruction, size_t index) {
2461 return nullptr;
2462}
2463
2464static IrInstruction *ir_instruction_return_get_dep(IrInstructionReturn *instruction, size_t index) {
2465 switch (index) {
2466 case 0: return instruction->value;
2467 default: return nullptr;
2468 }
2469}
2470
2471static IrInstruction *ir_instruction_cast_get_dep(IrInstructionCast *instruction, size_t index) {
2472 switch (index) {
2473 case 0: return instruction->value;
2474 default: return nullptr;
2475 }
2476}
2477
2478static IrInstruction *ir_instruction_containerinitlist_get_dep(IrInstructionContainerInitList *instruction,
2479 size_t index)
2480{
2481 if (index == 0) return instruction->container_type;
2482 size_t item_index = index - 1;
2483 if (item_index < instruction->item_count) return instruction->items[item_index];
2484 return nullptr;
2485}
2486
2487static IrInstruction *ir_instruction_containerinitfields_get_dep(IrInstructionContainerInitFields *instruction,
2488 size_t index)
2489{
2490 if (index == 0) return instruction->container_type;
2491 size_t field_index = index - 1;
2492 if (field_index < instruction->field_count) return instruction->fields[field_index].value;
2493 return nullptr;
2494}
2495
2496static IrInstruction *ir_instruction_structinit_get_dep(IrInstructionStructInit *instruction, size_t index) {
2497 if (index < instruction->field_count) return instruction->fields[index].value;
2498 return nullptr;
2499}
2500
2501static IrInstruction *ir_instruction_unioninit_get_dep(IrInstructionUnionInit *instruction, size_t index) {
2502 switch (index) {
2503 case 0: return instruction->init_value;
2504 default: return nullptr;
2505 }
2506}
2507
2508static IrInstruction *ir_instruction_unreachable_get_dep(IrInstructionUnreachable *instruction, size_t index) {
2509 return nullptr;
2510}
2511
2512static IrInstruction *ir_instruction_typeof_get_dep(IrInstructionTypeOf *instruction, size_t index) {
2513 switch (index) {
2514 case 0: return instruction->value;
2515 default: return nullptr;
2516 }
2517}
2518
2519static IrInstruction *ir_instruction_toptrtype_get_dep(IrInstructionToPtrType *instruction, size_t index) {
2520 switch (index) {
2521 case 0: return instruction->value;
2522 default: return nullptr;
2523 }
2524}
2525
2526static IrInstruction *ir_instruction_ptrtypechild_get_dep(IrInstructionPtrTypeChild *instruction, size_t index) {
2527 switch (index) {
2528 case 0: return instruction->value;
2529 default: return nullptr;
2530 }
2531}
2532
2533static IrInstruction *ir_instruction_setdebugsafety_get_dep(IrInstructionSetDebugSafety *instruction, size_t index) {
2534 switch (index) {
2535 case 0: return instruction->scope_value;
2536 case 1: return instruction->debug_safety_on;
2537 default: return nullptr;
2538 }
2539}
2540
2541static IrInstruction *ir_instruction_setfloatmode_get_dep(IrInstructionSetFloatMode *instruction, size_t index) {
2542 switch (index) {
2543 case 0: return instruction->scope_value;
2544 case 1: return instruction->mode_value;
2545 default: return nullptr;
2546 }
2547}
2548
2549static IrInstruction *ir_instruction_arraytype_get_dep(IrInstructionArrayType *instruction, size_t index) {
2550 switch (index) {
2551 case 0: return instruction->size;
2552 case 1: return instruction->child_type;
2553 default: return nullptr;
2554 }
2555}
2556
2557static IrInstruction *ir_instruction_slicetype_get_dep(IrInstructionSliceType *instruction, size_t index) {
2558 switch (index) {
2559 case 0: return instruction->child_type;
2560 default: return nullptr;
2561 }
2562}
2563
2564static IrInstruction *ir_instruction_asm_get_dep(IrInstructionAsm *instruction, size_t index) {
2565 AstNode *asm_node = instruction->base.source_node;
2566 if (index < asm_node->data.asm_expr.output_list.length) return instruction->output_types[index];
2567 size_t input_index = index - asm_node->data.asm_expr.output_list.length;
2568 if (input_index < asm_node->data.asm_expr.input_list.length) return instruction->input_list[input_index];
2569 return nullptr;
2570}
2571
2572static IrInstruction *ir_instruction_sizeof_get_dep(IrInstructionSizeOf *instruction, size_t index) {
2573 switch (index) {
2574 case 0: return instruction->type_value;
2575 default: return nullptr;
2576 }
2577}
2578
2579static IrInstruction *ir_instruction_testnonnull_get_dep(IrInstructionTestNonNull *instruction, size_t index) {
2580 switch (index) {
2581 case 0: return instruction->value;
2582 default: return nullptr;
2583 }
2584}
2585
2586static IrInstruction *ir_instruction_unwrapmaybe_get_dep(IrInstructionUnwrapMaybe *instruction, size_t index) {
2587 switch (index) {
2588 case 0: return instruction->value;
2589 default: return nullptr;
2590 }
2591}
2592
2593static IrInstruction *ir_instruction_maybewrap_get_dep(IrInstructionMaybeWrap *instruction, size_t index) {
2594 switch (index) {
2595 case 0: return instruction->value;
2596 default: return nullptr;
2597 }
2598}
2599
2600static IrInstruction *ir_instruction_uniontag_get_dep(IrInstructionUnionTag *instruction, size_t index) {
2601 switch (index) {
2602 case 0: return instruction->value;
2603 default: return nullptr;
2604 }
2605}
2606
2607static IrInstruction *ir_instruction_clz_get_dep(IrInstructionClz *instruction, size_t index) {
2608 switch (index) {
2609 case 0: return instruction->value;
2610 default: return nullptr;
2611 }
2612}
2613
2614static IrInstruction *ir_instruction_ctz_get_dep(IrInstructionCtz *instruction, size_t index) {
2615 switch (index) {
2616 case 0: return instruction->value;
2617 default: return nullptr;
2618 }
2619}
2620
2621static IrInstruction *ir_instruction_import_get_dep(IrInstructionImport *instruction, size_t index) {
2622 switch (index) {
2623 case 0: return instruction->name;
2624 default: return nullptr;
2625 }
2626}
2627
2628static IrInstruction *ir_instruction_cimport_get_dep(IrInstructionCImport *instruction, size_t index) {
2629 return nullptr;
2630}
2631
2632static IrInstruction *ir_instruction_cinclude_get_dep(IrInstructionCInclude *instruction, size_t index) {
2633 switch (index) {
2634 case 0: return instruction->name;
2635 default: return nullptr;
2636 }
2637}
2638
2639static IrInstruction *ir_instruction_cdefine_get_dep(IrInstructionCDefine *instruction, size_t index) {
2640 switch (index) {
2641 case 0: return instruction->name;
2642 case 1: return instruction->value;
2643 default: return nullptr;
2644 }
2645}
2646
2647static IrInstruction *ir_instruction_cundef_get_dep(IrInstructionCUndef *instruction, size_t index) {
2648 switch (index) {
2649 case 0: return instruction->name;
2650 default: return nullptr;
2651 }
2652}
2653
2654static IrInstruction *ir_instruction_arraylen_get_dep(IrInstructionArrayLen *instruction, size_t index) {
2655 switch (index) {
2656 case 0: return instruction->array_value;
2657 default: return nullptr;
2658 }
2659}
2660
2661static IrInstruction *ir_instruction_ref_get_dep(IrInstructionRef *instruction, size_t index) {
2662 switch (index) {
2663 case 0: return instruction->value;
2664 default: return nullptr;
2665 }
2666}
2667
2668static IrInstruction *ir_instruction_minvalue_get_dep(IrInstructionMinValue *instruction, size_t index) {
2669 switch (index) {
2670 case 0: return instruction->value;
2671 default: return nullptr;
2672 }
2673}
2674
2675static IrInstruction *ir_instruction_maxvalue_get_dep(IrInstructionMaxValue *instruction, size_t index) {
2676 switch (index) {
2677 case 0: return instruction->value;
2678 default: return nullptr;
2679 }
2680}
2681
2682static IrInstruction *ir_instruction_compileerr_get_dep(IrInstructionCompileErr *instruction, size_t index) {
2683 switch (index) {
2684 case 0: return instruction->msg;
2685 default: return nullptr;
2686 }
2687}
2688
2689static IrInstruction *ir_instruction_compilelog_get_dep(IrInstructionCompileLog *instruction, size_t index) {
2690 if (index < instruction->msg_count)
2691 return instruction->msg_list[index];
2692 return nullptr;
2693}
2694
2695static IrInstruction *ir_instruction_errname_get_dep(IrInstructionErrName *instruction, size_t index) {
2696 switch (index) {
2697 case 0: return instruction->value;
2698 default: return nullptr;
2699 }
2700}
2701
2702static IrInstruction *ir_instruction_embedfile_get_dep(IrInstructionEmbedFile *instruction, size_t index) {
2703 switch (index) {
2704 case 0: return instruction->name;
2705 default: return nullptr;
2706 }
2707}
2708
2709static IrInstruction *ir_instruction_cmpxchg_get_dep(IrInstructionCmpxchg *instruction, size_t index) {
2710 switch (index) {
2711 case 0: return instruction->ptr;
2712 case 1: return instruction->cmp_value;
2713 case 2: return instruction->new_value;
2714 case 3: return instruction->success_order_value;
2715 case 4: return instruction->failure_order_value;
2716 default: return nullptr;
2717 }
2718}
2719
2720static IrInstruction *ir_instruction_fence_get_dep(IrInstructionFence *instruction, size_t index) {
2721 switch (index) {
2722 case 0: return instruction->order_value;
2723 default: return nullptr;
2724 }
2725}
2726
2727static IrInstruction *ir_instruction_truncate_get_dep(IrInstructionTruncate *instruction, size_t index) {
2728 switch (index) {
2729 case 0: return instruction->dest_type;
2730 case 1: return instruction->target;
2731 default: return nullptr;
2732 }
2733}
2734
2735static IrInstruction *ir_instruction_inttype_get_dep(IrInstructionIntType *instruction, size_t index) {
2736 switch (index) {
2737 case 0: return instruction->is_signed;
2738 case 1: return instruction->bit_count;
2739 default: return nullptr;
2740 }
2741}
2742
2743static IrInstruction *ir_instruction_boolnot_get_dep(IrInstructionBoolNot *instruction, size_t index) {
2744 switch (index) {
2745 case 0: return instruction->value;
2746 default: return nullptr;
2747 }
2748}
2749
2750static IrInstruction *ir_instruction_memset_get_dep(IrInstructionMemset *instruction, size_t index) {
2751 switch (index) {
2752 case 0: return instruction->dest_ptr;
2753 case 1: return instruction->byte;
2754 case 2: return instruction->count;
2755 default: return nullptr;
2756 }
2757}
2758
2759static IrInstruction *ir_instruction_memcpy_get_dep(IrInstructionMemcpy *instruction, size_t index) {
2760 switch (index) {
2761 case 0: return instruction->dest_ptr;
2762 case 1: return instruction->src_ptr;
2763 case 2: return instruction->count;
2764 default: return nullptr;
2765 }
2766}
2767
2768static IrInstruction *ir_instruction_slice_get_dep(IrInstructionSlice *instruction, size_t index) {
2769 switch (index) {
2770 case 0: return instruction->ptr;
2771 case 1: return instruction->start;
2772 case 2: return instruction->end;
2773 default: return nullptr;
2774 }
2775}
2776
2777static IrInstruction *ir_instruction_membercount_get_dep(IrInstructionMemberCount *instruction, size_t index) {
2778 switch (index) {
2779 case 0: return instruction->container;
2780 default: return nullptr;
2781 }
2782}
2783
2784static IrInstruction *ir_instruction_membertype_get_dep(IrInstructionMemberType *instruction, size_t index) {
2785 switch (index) {
2786 case 0: return instruction->container_type;
2787 case 1: return instruction->member_index;
2788 default: return nullptr;
2789 }
2790}
2791
2792static IrInstruction *ir_instruction_membername_get_dep(IrInstructionMemberName *instruction, size_t index) {
2793 switch (index) {
2794 case 0: return instruction->container_type;
2795 case 1: return instruction->member_index;
2796 default: return nullptr;
2797 }
2798}
2799
2800static IrInstruction *ir_instruction_breakpoint_get_dep(IrInstructionBreakpoint *instruction, size_t index) {
2801 return nullptr;
2802}
2803
2804static IrInstruction *ir_instruction_returnaddress_get_dep(IrInstructionReturnAddress *instruction, size_t index) {
2805 return nullptr;
2806}
2807
2808static IrInstruction *ir_instruction_frameaddress_get_dep(IrInstructionFrameAddress *instruction, size_t index) {
2809 return nullptr;
2810}
2811
2812static IrInstruction *ir_instruction_alignof_get_dep(IrInstructionAlignOf *instruction, size_t index) {
2813 switch (index) {
2814 case 0: return instruction->type_value;
2815 default: return nullptr;
2816 }
2817}
2818
2819static IrInstruction *ir_instruction_overflowop_get_dep(IrInstructionOverflowOp *instruction, size_t index) {
2820 switch (index) {
2821 case 0: return instruction->type_value;
2822 case 1: return instruction->op1;
2823 case 2: return instruction->op2;
2824 case 3: return instruction->result_ptr;
2825 default: return nullptr;
2826 }
2827}
2828
2829static IrInstruction *ir_instruction_testerr_get_dep(IrInstructionTestErr *instruction, size_t index) {
2830 switch (index) {
2831 case 0: return instruction->value;
2832 default: return nullptr;
2833 }
2834}
2835
2836static IrInstruction *ir_instruction_unwraperrcode_get_dep(IrInstructionUnwrapErrCode *instruction, size_t index) {
2837 switch (index) {
2838 case 0: return instruction->value;
2839 default: return nullptr;
2840 }
2841}
2842
2843static IrInstruction *ir_instruction_unwraperrpayload_get_dep(IrInstructionUnwrapErrPayload *instruction,
2844 size_t index)
2845{
2846 switch (index) {
2847 case 0: return instruction->value;
2848 default: return nullptr;
2849 }
2850}
2851
2852static IrInstruction *ir_instruction_errwrapcode_get_dep(IrInstructionErrWrapCode *instruction, size_t index) {
2853 switch (index) {
2854 case 0: return instruction->value;
2855 default: return nullptr;
2856 }
2857}
2858
2859static IrInstruction *ir_instruction_errwrappayload_get_dep(IrInstructionErrWrapPayload *instruction, size_t index) {
2860 switch (index) {
2861 case 0: return instruction->value;
2862 default: return nullptr;
2863 }
2864}
2865
2866static IrInstruction *ir_instruction_fnproto_get_dep(IrInstructionFnProto *instruction, size_t index) {
2867 if (index == 0) return instruction->return_type;
2868 size_t param_index = index - 1;
2869 if (param_index < instruction->base.source_node->data.fn_proto.params.length) {
2870 return instruction->param_types[param_index];
2871 }
2872 size_t next_index = param_index - instruction->base.source_node->data.fn_proto.params.length;
2873 if (next_index == 0 && instruction->align_value != nullptr) {
2874 return instruction->align_value;
2875 }
2876 return nullptr;
2877}
2878
2879static IrInstruction *ir_instruction_testcomptime_get_dep(IrInstructionTestComptime *instruction, size_t index) {
2880 switch (index) {
2881 case 0: return instruction->value;
2882 default: return nullptr;
2883 }
2884}
2885
2886static IrInstruction *ir_instruction_ptrcast_get_dep(IrInstructionPtrCast *instruction,
2887 size_t index)
2888{
2889 switch (index) {
2890 case 0: return instruction->ptr;
2891 case 1: return instruction->dest_type;
2892 default: return nullptr;
2893 }
2894}
2895
2896static IrInstruction *ir_instruction_bitcast_get_dep(IrInstructionBitCast *instruction,
2897 size_t index)
2898{
2899 switch (index) {
2900 case 0: return instruction->value;
2901 case 1: return instruction->dest_type;
2902 default: return nullptr;
2903 }
2904}
2905
2906static IrInstruction *ir_instruction_widenorshorten_get_dep(IrInstructionWidenOrShorten *instruction, size_t index) {
2907 switch (index) {
2908 case 0: return instruction->target;
2909 default: return nullptr;
2910 }
2911}
2912
2913static IrInstruction *ir_instruction_inttoptr_get_dep(IrInstructionIntToPtr *instruction, size_t index) {
2914 switch (index) {
2915 case 0: return instruction->target;
2916 case 1: return instruction->dest_type;
2917 default: return nullptr;
2918 }
2919}
2920
2921static IrInstruction *ir_instruction_ptrtoint_get_dep(IrInstructionPtrToInt *instruction, size_t index) {
2922 switch (index) {
2923 case 0: return instruction->target;
2924 default: return nullptr;
2925 }
2926}
2927
2928static IrInstruction *ir_instruction_inttoenum_get_dep(IrInstructionIntToEnum *instruction, size_t index) {
2929 switch (index) {
2930 case 0: return instruction->target;
2931 default: return nullptr;
2932 }
2933}
2934
2935static IrInstruction *ir_instruction_inttoerr_get_dep(IrInstructionIntToErr *instruction, size_t index) {
2936 switch (index) {
2937 case 0: return instruction->target;
2938 default: return nullptr;
2939 }
2940}
2941
2942static IrInstruction *ir_instruction_errtoint_get_dep(IrInstructionErrToInt *instruction, size_t index) {
2943 switch (index) {
2944 case 0: return instruction->target;
2945 default: return nullptr;
2946 }
2947}
2948
2949static IrInstruction *ir_instruction_checkswitchprongs_get_dep(IrInstructionCheckSwitchProngs *instruction,
2950 size_t index)
2951{
2952 if (index == 0) return instruction->target_value;
2953 size_t range_index = index - 1;
2954 if (range_index < instruction->range_count * 2) {
2955 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_index / 2];
2956 return (range_index % 2 == 0) ? range->start : range->end;
2957 }
2958 return nullptr;
2959}
2960
2961static IrInstruction *ir_instruction_checkstatementisvoid_get_dep(IrInstructionCheckStatementIsVoid *instruction,
2962 size_t index)
2963{
2964 switch (index) {
2965 case 0: return instruction->statement_value;
2966 default: return nullptr;
2967 }
2968}
2969
2970static IrInstruction *ir_instruction_typename_get_dep(IrInstructionTypeName *instruction, size_t index) {
2971 switch (index) {
2972 case 0: return instruction->type_value;
2973 default: return nullptr;
2974 }
2975}
2976
2977static IrInstruction *ir_instruction_canimplicitcast_get_dep(IrInstructionCanImplicitCast *instruction, size_t index) {
2978 switch (index) {
2979 case 0: return instruction->type_value;
2980 case 1: return instruction->target_value;
2981 default: return nullptr;
2982 }
2983}
2984
2985static IrInstruction *ir_instruction_declref_get_dep(IrInstructionDeclRef *instruction, size_t index) {
2986 return nullptr;
2987}
2254static IrInstruction *ir_build_set_eval_branch_quota(IrBuilder *irb, Scope *scope, AstNode *source_node,
2255 IrInstruction *new_quota)
2256{
2257 IrInstructionSetEvalBranchQuota *instruction = ir_build_instruction<IrInstructionSetEvalBranchQuota>(irb, scope, source_node);
2258 instruction->new_quota = new_quota;
29882259
2989static IrInstruction *ir_instruction_panic_get_dep(IrInstructionPanic *instruction, size_t index) {
2990 switch (index) {
2991 case 0: return instruction->msg;
2992 default: return nullptr;
2993 }
2994}
2260 ir_ref_instruction(new_quota, irb->current_basic_block);
29952261
2996static IrInstruction *ir_instruction_enumtagname_get_dep(IrInstructionTagName *instruction, size_t index) {
2997 switch (index) {
2998 case 0: return instruction->target;
2999 default: return nullptr;
3000 }
2262 return &instruction->base;
30012263}
30022264
3003static IrInstruction *ir_instruction_enumtagtype_get_dep(IrInstructionTagType *instruction, size_t index) {
3004 switch (index) {
3005 case 0: return instruction->target;
3006 default: return nullptr;
3007 }
3008}
2265static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode *source_node,
2266 IrInstruction *align_bytes, IrInstruction *target)
2267{
2268 IrInstructionAlignCast *instruction = ir_build_instruction<IrInstructionAlignCast>(irb, scope, source_node);
2269 instruction->align_bytes = align_bytes;
2270 instruction->target = target;
30092271
3010static IrInstruction *ir_instruction_fieldparentptr_get_dep(IrInstructionFieldParentPtr *instruction, size_t index) {
3011 switch (index) {
3012 case 0: return instruction->type_value;
3013 case 1: return instruction->field_name;
3014 case 2: return instruction->field_ptr;
3015 default: return nullptr;
3016 }
3017}
2272 if (align_bytes) ir_ref_instruction(align_bytes, irb->current_basic_block);
2273 ir_ref_instruction(target, irb->current_basic_block);
30182274
3019static IrInstruction *ir_instruction_offsetof_get_dep(IrInstructionOffsetOf *instruction, size_t index) {
3020 switch (index) {
3021 case 0: return instruction->type_value;
3022 case 1: return instruction->field_name;
3023 default: return nullptr;
3024 }
2275 return &instruction->base;
30252276}
30262277
3027static IrInstruction *ir_instruction_typeid_get_dep(IrInstructionTypeId *instruction, size_t index) {
3028 switch (index) {
3029 case 0: return instruction->type_value;
3030 default: return nullptr;
3031 }
3032}
2278static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) {
2279 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node);
30332280
3034static IrInstruction *ir_instruction_setevalbranchquota_get_dep(IrInstructionSetEvalBranchQuota *instruction, size_t index) {
3035 switch (index) {
3036 case 0: return instruction->new_quota;
3037 default: return nullptr;
3038 }
2281 return &instruction->base;
30392282}
30402283
3041static IrInstruction *ir_instruction_ptrtypeof_get_dep(IrInstructionPtrTypeOf *instruction, size_t index) {
3042 switch (index) {
3043 case 0: return instruction->align_value;
3044 case 1: return instruction->child_type;
3045 default: return nullptr;
3046 }
3047}
2284static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, AstNode *source_node,
2285 IrInstruction *align_bytes)
2286{
2287 IrInstructionSetAlignStack *instruction = ir_build_instruction<IrInstructionSetAlignStack>(irb, scope, source_node);
2288 instruction->align_bytes = align_bytes;
30482289
3049static IrInstruction *ir_instruction_aligncast_get_dep(IrInstructionAlignCast *instruction, size_t index) {
3050 switch (index) {
3051 case 0: return instruction->target;
3052 case 1: return instruction->align_bytes; // can be null
3053 default: return nullptr;
3054 }
3055}
2290 ir_ref_instruction(align_bytes, irb->current_basic_block);
30562291
3057static IrInstruction *ir_instruction_opaquetype_get_dep(IrInstructionOpaqueType *instruction, size_t index) {
3058 return nullptr;
2292 return &instruction->base;
30592293}
30602294
3061static IrInstruction *ir_instruction_setalignstack_get_dep(IrInstructionSetAlignStack *instruction, size_t index) {
3062 switch (index) {
3063 case 0: return instruction->align_bytes;
3064 default: return nullptr;
3065 }
3066}
2295static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
2296 IrInstruction *fn_type, IrInstruction *arg_index)
2297{
2298 IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node);
2299 instruction->fn_type = fn_type;
2300 instruction->arg_index = arg_index;
30672301
3068static IrInstruction *ir_instruction_argtype_get_dep(IrInstructionArgType *instruction, size_t index) {
3069 switch (index) {
3070 case 0: return instruction->fn_type;
3071 case 1: return instruction->arg_index;
3072 default: return nullptr;
3073 }
3074}
2302 ir_ref_instruction(fn_type, irb->current_basic_block);
2303 ir_ref_instruction(arg_index, irb->current_basic_block);
30752304
3076static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t index) {
3077 switch (instruction->id) {
3078 case IrInstructionIdInvalid:
3079 zig_unreachable();
3080 case IrInstructionIdBr:
3081 return ir_instruction_br_get_dep((IrInstructionBr *) instruction, index);
3082 case IrInstructionIdCondBr:
3083 return ir_instruction_condbr_get_dep((IrInstructionCondBr *) instruction, index);
3084 case IrInstructionIdSwitchBr:
3085 return ir_instruction_switchbr_get_dep((IrInstructionSwitchBr *) instruction, index);
3086 case IrInstructionIdSwitchVar:
3087 return ir_instruction_switchvar_get_dep((IrInstructionSwitchVar *) instruction, index);
3088 case IrInstructionIdSwitchTarget:
3089 return ir_instruction_switchtarget_get_dep((IrInstructionSwitchTarget *) instruction, index);
3090 case IrInstructionIdPhi:
3091 return ir_instruction_phi_get_dep((IrInstructionPhi *) instruction, index);
3092 case IrInstructionIdUnOp:
3093 return ir_instruction_unop_get_dep((IrInstructionUnOp *) instruction, index);
3094 case IrInstructionIdBinOp:
3095 return ir_instruction_binop_get_dep((IrInstructionBinOp *) instruction, index);
3096 case IrInstructionIdDeclVar:
3097 return ir_instruction_declvar_get_dep((IrInstructionDeclVar *) instruction, index);
3098 case IrInstructionIdExport:
3099 return ir_instruction_export_get_dep((IrInstructionExport *) instruction, index);
3100 case IrInstructionIdLoadPtr:
3101 return ir_instruction_loadptr_get_dep((IrInstructionLoadPtr *) instruction, index);
3102 case IrInstructionIdStorePtr:
3103 return ir_instruction_storeptr_get_dep((IrInstructionStorePtr *) instruction, index);
3104 case IrInstructionIdFieldPtr:
3105 return ir_instruction_fieldptr_get_dep((IrInstructionFieldPtr *) instruction, index);
3106 case IrInstructionIdStructFieldPtr:
3107 return ir_instruction_structfieldptr_get_dep((IrInstructionStructFieldPtr *) instruction, index);
3108 case IrInstructionIdUnionFieldPtr:
3109 return ir_instruction_unionfieldptr_get_dep((IrInstructionUnionFieldPtr *) instruction, index);
3110 case IrInstructionIdElemPtr:
3111 return ir_instruction_elemptr_get_dep((IrInstructionElemPtr *) instruction, index);
3112 case IrInstructionIdVarPtr:
3113 return ir_instruction_varptr_get_dep((IrInstructionVarPtr *) instruction, index);
3114 case IrInstructionIdCall:
3115 return ir_instruction_call_get_dep((IrInstructionCall *) instruction, index);
3116 case IrInstructionIdConst:
3117 return ir_instruction_const_get_dep((IrInstructionConst *) instruction, index);
3118 case IrInstructionIdReturn:
3119 return ir_instruction_return_get_dep((IrInstructionReturn *) instruction, index);
3120 case IrInstructionIdCast:
3121 return ir_instruction_cast_get_dep((IrInstructionCast *) instruction, index);
3122 case IrInstructionIdContainerInitList:
3123 return ir_instruction_containerinitlist_get_dep((IrInstructionContainerInitList *) instruction, index);
3124 case IrInstructionIdContainerInitFields:
3125 return ir_instruction_containerinitfields_get_dep((IrInstructionContainerInitFields *) instruction, index);
3126 case IrInstructionIdStructInit:
3127 return ir_instruction_structinit_get_dep((IrInstructionStructInit *) instruction, index);
3128 case IrInstructionIdUnionInit:
3129 return ir_instruction_unioninit_get_dep((IrInstructionUnionInit *) instruction, index);
3130 case IrInstructionIdUnreachable:
3131 return ir_instruction_unreachable_get_dep((IrInstructionUnreachable *) instruction, index);
3132 case IrInstructionIdTypeOf:
3133 return ir_instruction_typeof_get_dep((IrInstructionTypeOf *) instruction, index);
3134 case IrInstructionIdToPtrType:
3135 return ir_instruction_toptrtype_get_dep((IrInstructionToPtrType *) instruction, index);
3136 case IrInstructionIdPtrTypeChild:
3137 return ir_instruction_ptrtypechild_get_dep((IrInstructionPtrTypeChild *) instruction, index);
3138 case IrInstructionIdSetDebugSafety:
3139 return ir_instruction_setdebugsafety_get_dep((IrInstructionSetDebugSafety *) instruction, index);
3140 case IrInstructionIdSetFloatMode:
3141 return ir_instruction_setfloatmode_get_dep((IrInstructionSetFloatMode *) instruction, index);
3142 case IrInstructionIdArrayType:
3143 return ir_instruction_arraytype_get_dep((IrInstructionArrayType *) instruction, index);
3144 case IrInstructionIdSliceType:
3145 return ir_instruction_slicetype_get_dep((IrInstructionSliceType *) instruction, index);
3146 case IrInstructionIdAsm:
3147 return ir_instruction_asm_get_dep((IrInstructionAsm *) instruction, index);
3148 case IrInstructionIdSizeOf:
3149 return ir_instruction_sizeof_get_dep((IrInstructionSizeOf *) instruction, index);
3150 case IrInstructionIdTestNonNull:
3151 return ir_instruction_testnonnull_get_dep((IrInstructionTestNonNull *) instruction, index);
3152 case IrInstructionIdUnwrapMaybe:
3153 return ir_instruction_unwrapmaybe_get_dep((IrInstructionUnwrapMaybe *) instruction, index);
3154 case IrInstructionIdMaybeWrap:
3155 return ir_instruction_maybewrap_get_dep((IrInstructionMaybeWrap *) instruction, index);
3156 case IrInstructionIdUnionTag:
3157 return ir_instruction_uniontag_get_dep((IrInstructionUnionTag *) instruction, index);
3158 case IrInstructionIdClz:
3159 return ir_instruction_clz_get_dep((IrInstructionClz *) instruction, index);
3160 case IrInstructionIdCtz:
3161 return ir_instruction_ctz_get_dep((IrInstructionCtz *) instruction, index);
3162 case IrInstructionIdImport:
3163 return ir_instruction_import_get_dep((IrInstructionImport *) instruction, index);
3164 case IrInstructionIdCImport:
3165 return ir_instruction_cimport_get_dep((IrInstructionCImport *) instruction, index);
3166 case IrInstructionIdCInclude:
3167 return ir_instruction_cinclude_get_dep((IrInstructionCInclude *) instruction, index);
3168 case IrInstructionIdCDefine:
3169 return ir_instruction_cdefine_get_dep((IrInstructionCDefine *) instruction, index);
3170 case IrInstructionIdCUndef:
3171 return ir_instruction_cundef_get_dep((IrInstructionCUndef *) instruction, index);
3172 case IrInstructionIdArrayLen:
3173 return ir_instruction_arraylen_get_dep((IrInstructionArrayLen *) instruction, index);
3174 case IrInstructionIdRef:
3175 return ir_instruction_ref_get_dep((IrInstructionRef *) instruction, index);
3176 case IrInstructionIdMinValue:
3177 return ir_instruction_minvalue_get_dep((IrInstructionMinValue *) instruction, index);
3178 case IrInstructionIdMaxValue:
3179 return ir_instruction_maxvalue_get_dep((IrInstructionMaxValue *) instruction, index);
3180 case IrInstructionIdCompileErr:
3181 return ir_instruction_compileerr_get_dep((IrInstructionCompileErr *) instruction, index);
3182 case IrInstructionIdCompileLog:
3183 return ir_instruction_compilelog_get_dep((IrInstructionCompileLog *) instruction, index);
3184 case IrInstructionIdErrName:
3185 return ir_instruction_errname_get_dep((IrInstructionErrName *) instruction, index);
3186 case IrInstructionIdEmbedFile:
3187 return ir_instruction_embedfile_get_dep((IrInstructionEmbedFile *) instruction, index);
3188 case IrInstructionIdCmpxchg:
3189 return ir_instruction_cmpxchg_get_dep((IrInstructionCmpxchg *) instruction, index);
3190 case IrInstructionIdFence:
3191 return ir_instruction_fence_get_dep((IrInstructionFence *) instruction, index);
3192 case IrInstructionIdTruncate:
3193 return ir_instruction_truncate_get_dep((IrInstructionTruncate *) instruction, index);
3194 case IrInstructionIdIntType:
3195 return ir_instruction_inttype_get_dep((IrInstructionIntType *) instruction, index);
3196 case IrInstructionIdBoolNot:
3197 return ir_instruction_boolnot_get_dep((IrInstructionBoolNot *) instruction, index);
3198 case IrInstructionIdMemset:
3199 return ir_instruction_memset_get_dep((IrInstructionMemset *) instruction, index);
3200 case IrInstructionIdMemcpy:
3201 return ir_instruction_memcpy_get_dep((IrInstructionMemcpy *) instruction, index);
3202 case IrInstructionIdSlice:
3203 return ir_instruction_slice_get_dep((IrInstructionSlice *) instruction, index);
3204 case IrInstructionIdMemberCount:
3205 return ir_instruction_membercount_get_dep((IrInstructionMemberCount *) instruction, index);
3206 case IrInstructionIdMemberType:
3207 return ir_instruction_membertype_get_dep((IrInstructionMemberType *) instruction, index);
3208 case IrInstructionIdMemberName:
3209 return ir_instruction_membername_get_dep((IrInstructionMemberName *) instruction, index);
3210 case IrInstructionIdBreakpoint:
3211 return ir_instruction_breakpoint_get_dep((IrInstructionBreakpoint *) instruction, index);
3212 case IrInstructionIdReturnAddress:
3213 return ir_instruction_returnaddress_get_dep((IrInstructionReturnAddress *) instruction, index);
3214 case IrInstructionIdFrameAddress:
3215 return ir_instruction_frameaddress_get_dep((IrInstructionFrameAddress *) instruction, index);
3216 case IrInstructionIdAlignOf:
3217 return ir_instruction_alignof_get_dep((IrInstructionAlignOf *) instruction, index);
3218 case IrInstructionIdOverflowOp:
3219 return ir_instruction_overflowop_get_dep((IrInstructionOverflowOp *) instruction, index);
3220 case IrInstructionIdTestErr:
3221 return ir_instruction_testerr_get_dep((IrInstructionTestErr *) instruction, index);
3222 case IrInstructionIdUnwrapErrCode:
3223 return ir_instruction_unwraperrcode_get_dep((IrInstructionUnwrapErrCode *) instruction, index);
3224 case IrInstructionIdUnwrapErrPayload:
3225 return ir_instruction_unwraperrpayload_get_dep((IrInstructionUnwrapErrPayload *) instruction, index);
3226 case IrInstructionIdErrWrapCode:
3227 return ir_instruction_errwrapcode_get_dep((IrInstructionErrWrapCode *) instruction, index);
3228 case IrInstructionIdErrWrapPayload:
3229 return ir_instruction_errwrappayload_get_dep((IrInstructionErrWrapPayload *) instruction, index);
3230 case IrInstructionIdFnProto:
3231 return ir_instruction_fnproto_get_dep((IrInstructionFnProto *) instruction, index);
3232 case IrInstructionIdTestComptime:
3233 return ir_instruction_testcomptime_get_dep((IrInstructionTestComptime *) instruction, index);
3234 case IrInstructionIdPtrCast:
3235 return ir_instruction_ptrcast_get_dep((IrInstructionPtrCast *) instruction, index);
3236 case IrInstructionIdBitCast:
3237 return ir_instruction_bitcast_get_dep((IrInstructionBitCast *) instruction, index);
3238 case IrInstructionIdWidenOrShorten:
3239 return ir_instruction_widenorshorten_get_dep((IrInstructionWidenOrShorten *) instruction, index);
3240 case IrInstructionIdIntToPtr:
3241 return ir_instruction_inttoptr_get_dep((IrInstructionIntToPtr *) instruction, index);
3242 case IrInstructionIdPtrToInt:
3243 return ir_instruction_ptrtoint_get_dep((IrInstructionPtrToInt *) instruction, index);
3244 case IrInstructionIdIntToEnum:
3245 return ir_instruction_inttoenum_get_dep((IrInstructionIntToEnum *) instruction, index);
3246 case IrInstructionIdIntToErr:
3247 return ir_instruction_inttoerr_get_dep((IrInstructionIntToErr *) instruction, index);
3248 case IrInstructionIdErrToInt:
3249 return ir_instruction_errtoint_get_dep((IrInstructionErrToInt *) instruction, index);
3250 case IrInstructionIdCheckSwitchProngs:
3251 return ir_instruction_checkswitchprongs_get_dep((IrInstructionCheckSwitchProngs *) instruction, index);
3252 case IrInstructionIdCheckStatementIsVoid:
3253 return ir_instruction_checkstatementisvoid_get_dep((IrInstructionCheckStatementIsVoid *) instruction, index);
3254 case IrInstructionIdTypeName:
3255 return ir_instruction_typename_get_dep((IrInstructionTypeName *) instruction, index);
3256 case IrInstructionIdCanImplicitCast:
3257 return ir_instruction_canimplicitcast_get_dep((IrInstructionCanImplicitCast *) instruction, index);
3258 case IrInstructionIdDeclRef:
3259 return ir_instruction_declref_get_dep((IrInstructionDeclRef *) instruction, index);
3260 case IrInstructionIdPanic:
3261 return ir_instruction_panic_get_dep((IrInstructionPanic *) instruction, index);
3262 case IrInstructionIdTagName:
3263 return ir_instruction_enumtagname_get_dep((IrInstructionTagName *) instruction, index);
3264 case IrInstructionIdTagType:
3265 return ir_instruction_enumtagtype_get_dep((IrInstructionTagType *) instruction, index);
3266 case IrInstructionIdFieldParentPtr:
3267 return ir_instruction_fieldparentptr_get_dep((IrInstructionFieldParentPtr *) instruction, index);
3268 case IrInstructionIdOffsetOf:
3269 return ir_instruction_offsetof_get_dep((IrInstructionOffsetOf *) instruction, index);
3270 case IrInstructionIdTypeId:
3271 return ir_instruction_typeid_get_dep((IrInstructionTypeId *) instruction, index);
3272 case IrInstructionIdSetEvalBranchQuota:
3273 return ir_instruction_setevalbranchquota_get_dep((IrInstructionSetEvalBranchQuota *) instruction, index);
3274 case IrInstructionIdPtrTypeOf:
3275 return ir_instruction_ptrtypeof_get_dep((IrInstructionPtrTypeOf *) instruction, index);
3276 case IrInstructionIdAlignCast:
3277 return ir_instruction_aligncast_get_dep((IrInstructionAlignCast *) instruction, index);
3278 case IrInstructionIdOpaqueType:
3279 return ir_instruction_opaquetype_get_dep((IrInstructionOpaqueType *) instruction, index);
3280 case IrInstructionIdSetAlignStack:
3281 return ir_instruction_setalignstack_get_dep((IrInstructionSetAlignStack *) instruction, index);
3282 case IrInstructionIdArgType:
3283 return ir_instruction_argtype_get_dep((IrInstructionArgType *) instruction, index);
3284 }
3285 zig_unreachable();
2305 return &instruction->base;
32862306}
32872307
32882308static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
......@@ -3340,6 +2360,11 @@ static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) {
33402360 irb->current_basic_block = basic_block;
33412361}
33422362
2363static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) {
2364 irb->exec->basic_block_list.append(basic_block);
2365 ir_set_cursor_at_end(irb, basic_block);
2366}
2367
33432368static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) {
33442369 while (scope) {
33452370 if (scope->id == ScopeIdDeferExpr)
......@@ -3388,8 +2413,8 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
33882413 size_t defer_counts[2];
33892414 ir_count_defers(irb, scope, outer_scope, defer_counts);
33902415 if (defer_counts[ReturnKindError] > 0) {
3391 IrBasicBlock *err_block = ir_build_basic_block(irb, scope, "ErrRetErr");
3392 IrBasicBlock *ok_block = ir_build_basic_block(irb, scope, "ErrRetOk");
2416 IrBasicBlock *err_block = ir_create_basic_block(irb, scope, "ErrRetErr");
2417 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk");
33932418
33942419 IrInstruction *is_err = ir_build_test_err(irb, scope, node, return_value);
33952420
......@@ -3402,11 +2427,11 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
34022427
34032428 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime));
34042429
3405 ir_set_cursor_at_end(irb, err_block);
2430 ir_set_cursor_at_end_and_append_block(irb, err_block);
34062431 ir_gen_defers_for_block(irb, scope, outer_scope, true);
34072432 ir_build_return(irb, scope, node, return_value);
34082433
3409 ir_set_cursor_at_end(irb, ok_block);
2434 ir_set_cursor_at_end_and_append_block(irb, ok_block);
34102435 ir_gen_defers_for_block(irb, scope, outer_scope, false);
34112436 return ir_build_return(irb, scope, node, return_value);
34122437 } else {
......@@ -3424,17 +2449,17 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
34242449 IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr);
34252450 IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_val);
34262451
3427 IrBasicBlock *return_block = ir_build_basic_block(irb, scope, "ErrRetReturn");
3428 IrBasicBlock *continue_block = ir_build_basic_block(irb, scope, "ErrRetContinue");
2452 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn");
2453 IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue");
34292454 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, ir_should_inline(irb->exec, scope));
34302455 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime));
34312456
3432 ir_set_cursor_at_end(irb, return_block);
2457 ir_set_cursor_at_end_and_append_block(irb, return_block);
34332458 ir_gen_defers_for_block(irb, scope, outer_scope, true);
34342459 IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr);
34352460 ir_build_return(irb, scope, node, err_val);
34362461
3437 ir_set_cursor_at_end(irb, continue_block);
2462 ir_set_cursor_at_end_and_append_block(irb, continue_block);
34382463 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false);
34392464 if (lval.is_ptr)
34402465 return unwrapped_ptr;
......@@ -3529,13 +2554,13 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
35292554
35302555 if (block_node->data.block.statements.length == 0) {
35312556 // {}
3532 return ir_mark_gen(ir_build_const_void(irb, child_scope, block_node));
2557 return ir_build_const_void(irb, child_scope, block_node);
35332558 }
35342559
35352560 if (block_node->data.block.name != nullptr) {
35362561 scope_block->incoming_blocks = &incoming_blocks;
35372562 scope_block->incoming_values = &incoming_values;
3538 scope_block->end_block = ir_build_basic_block(irb, parent_scope, "BlockEnd");
2563 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd");
35392564 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, ir_should_inline(irb->exec, parent_scope));
35402565 }
35412566
......@@ -3558,7 +2583,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
35582583 // variable declarations start a new scope
35592584 IrInstructionDeclVar *decl_var_instruction = (IrInstructionDeclVar *)statement_value;
35602585 child_scope = decl_var_instruction->var->child_scope;
3561 } else if (statement_value != irb->codegen->invalid_instruction) {
2586 } else if (statement_value != irb->codegen->invalid_instruction && !is_continuation_unreachable) {
35622587 // this statement's value must be void
35632588 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value));
35642589 }
......@@ -3577,7 +2602,7 @@ static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode
35772602 if (block_node->data.block.name != nullptr) {
35782603 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
35792604 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime));
3580 ir_set_cursor_at_end(irb, scope_block->end_block);
2605 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block);
35812606 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
35822607 } else {
35832608 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false);
......@@ -3635,13 +2660,13 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node
36352660 }
36362661
36372662 // block for when val1 == false
3638 IrBasicBlock *false_block = ir_build_basic_block(irb, scope, "BoolOrFalse");
2663 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse");
36392664 // block for when val1 == true (don't even evaluate the second part)
3640 IrBasicBlock *true_block = ir_build_basic_block(irb, scope, "BoolOrTrue");
2665 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue");
36412666
36422667 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime);
36432668
3644 ir_set_cursor_at_end(irb, false_block);
2669 ir_set_cursor_at_end_and_append_block(irb, false_block);
36452670 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
36462671 if (val2 == irb->codegen->invalid_instruction)
36472672 return irb->codegen->invalid_instruction;
......@@ -3649,7 +2674,7 @@ static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node
36492674
36502675 ir_build_br(irb, scope, node, true_block, is_comptime);
36512676
3652 ir_set_cursor_at_end(irb, true_block);
2677 ir_set_cursor_at_end_and_append_block(irb, true_block);
36532678
36542679 IrInstruction **incoming_values = allocate<IrInstruction *>(2);
36552680 incoming_values[0] = val1;
......@@ -3677,13 +2702,13 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod
36772702 }
36782703
36792704 // block for when val1 == true
3680 IrBasicBlock *true_block = ir_build_basic_block(irb, scope, "BoolAndTrue");
2705 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue");
36812706 // block for when val1 == false (don't even evaluate the second part)
3682 IrBasicBlock *false_block = ir_build_basic_block(irb, scope, "BoolAndFalse");
2707 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse");
36832708
36842709 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime);
36852710
3686 ir_set_cursor_at_end(irb, true_block);
2711 ir_set_cursor_at_end_and_append_block(irb, true_block);
36872712 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope);
36882713 if (val2 == irb->codegen->invalid_instruction)
36892714 return irb->codegen->invalid_instruction;
......@@ -3691,7 +2716,7 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod
36912716
36922717 ir_build_br(irb, scope, node, false_block, is_comptime);
36932718
3694 ir_set_cursor_at_end(irb, false_block);
2719 ir_set_cursor_at_end_and_append_block(irb, false_block);
36952720
36962721 IrInstruction **incoming_values = allocate<IrInstruction *>(2);
36972722 incoming_values[0] = val1;
......@@ -3723,12 +2748,12 @@ static IrInstruction *ir_gen_maybe_ok_or(IrBuilder *irb, Scope *parent_scope, As
37232748 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_non_null);
37242749 }
37252750
3726 IrBasicBlock *ok_block = ir_build_basic_block(irb, parent_scope, "MaybeNonNull");
3727 IrBasicBlock *null_block = ir_build_basic_block(irb, parent_scope, "MaybeNull");
3728 IrBasicBlock *end_block = ir_build_basic_block(irb, parent_scope, "MaybeEnd");
2751 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "MaybeNonNull");
2752 IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "MaybeNull");
2753 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "MaybeEnd");
37292754 ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime);
37302755
3731 ir_set_cursor_at_end(irb, null_block);
2756 ir_set_cursor_at_end_and_append_block(irb, null_block);
37322757 IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope);
37332758 if (null_result == irb->codegen->invalid_instruction)
37342759 return irb->codegen->invalid_instruction;
......@@ -3736,13 +2761,13 @@ static IrInstruction *ir_gen_maybe_ok_or(IrBuilder *irb, Scope *parent_scope, As
37362761 if (!instr_is_unreachable(null_result))
37372762 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime));
37382763
3739 ir_set_cursor_at_end(irb, ok_block);
2764 ir_set_cursor_at_end_and_append_block(irb, ok_block);
37402765 IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, parent_scope, node, maybe_ptr, false);
37412766 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr);
37422767 IrBasicBlock *after_ok_block = irb->current_basic_block;
37432768 ir_build_br(irb, parent_scope, node, end_block, is_comptime);
37442769
3745 ir_set_cursor_at_end(irb, end_block);
2770 ir_set_cursor_at_end_and_append_block(irb, end_block);
37462771 IrInstruction **incoming_values = allocate<IrInstruction *>(2);
37472772 incoming_values[0] = null_result;
37482773 incoming_values[1] = unwrapped_payload;
......@@ -4748,13 +3773,14 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
47483773 AstNode *then_node = node->data.if_bool_expr.then_block;
47493774 AstNode *else_node = node->data.if_bool_expr.else_node;
47503775
4751 IrBasicBlock *then_block = ir_build_basic_block(irb, scope, "Then");
4752 IrBasicBlock *else_block = ir_build_basic_block(irb, scope, "Else");
4753 IrBasicBlock *endif_block = ir_build_basic_block(irb, scope, "EndIf");
3776 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "Then");
3777 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else");
3778 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf");
47543779
47553780 ir_build_cond_br(irb, scope, condition->source_node, condition, then_block, else_block, is_comptime);
47563781
4757 ir_set_cursor_at_end(irb, then_block);
3782 ir_set_cursor_at_end_and_append_block(irb, then_block);
3783
47583784 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, scope);
47593785 if (then_expr_result == irb->codegen->invalid_instruction)
47603786 return then_expr_result;
......@@ -4762,7 +3788,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
47623788 if (!instr_is_unreachable(then_expr_result))
47633789 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
47643790
4765 ir_set_cursor_at_end(irb, else_block);
3791 ir_set_cursor_at_end_and_append_block(irb, else_block);
47663792 IrInstruction *else_expr_result;
47673793 if (else_node) {
47683794 else_expr_result = ir_gen_node(irb, else_node, scope);
......@@ -4775,7 +3801,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
47753801 if (!instr_is_unreachable(else_expr_result))
47763802 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
47773803
4778 ir_set_cursor_at_end(irb, endif_block);
3804 ir_set_cursor_at_end_and_append_block(irb, endif_block);
47793805 IrInstruction **incoming_values = allocate<IrInstruction *>(2);
47803806 incoming_values[0] = then_expr_result;
47813807 incoming_values[1] = else_expr_result;
......@@ -5044,13 +4070,13 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
50444070 AstNode *continue_expr_node = node->data.while_expr.continue_expr;
50454071 AstNode *else_node = node->data.while_expr.else_node;
50464072
5047 IrBasicBlock *cond_block = ir_build_basic_block(irb, scope, "WhileCond");
5048 IrBasicBlock *body_block = ir_build_basic_block(irb, scope, "WhileBody");
4073 IrBasicBlock *cond_block = ir_create_basic_block(irb, scope, "WhileCond");
4074 IrBasicBlock *body_block = ir_create_basic_block(irb, scope, "WhileBody");
50494075 IrBasicBlock *continue_block = continue_expr_node ?
5050 ir_build_basic_block(irb, scope, "WhileContinue") : cond_block;
5051 IrBasicBlock *end_block = ir_build_basic_block(irb, scope, "WhileEnd");
4076 ir_create_basic_block(irb, scope, "WhileContinue") : cond_block;
4077 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "WhileEnd");
50524078 IrBasicBlock *else_block = else_node ?
5053 ir_build_basic_block(irb, scope, "WhileElse") : end_block;
4079 ir_create_basic_block(irb, scope, "WhileElse") : end_block;
50544080
50554081 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node,
50564082 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline);
......@@ -5059,7 +4085,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
50594085 Buf *var_symbol = node->data.while_expr.var_symbol;
50604086 Buf *err_symbol = node->data.while_expr.err_symbol;
50614087 if (err_symbol != nullptr) {
5062 ir_set_cursor_at_end(irb, cond_block);
4088 ir_set_cursor_at_end_and_append_block(irb, cond_block);
50634089
50644090 Scope *payload_scope;
50654091 AstNode *symbol_node = node; // TODO make more accurate
......@@ -5084,7 +4110,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
50844110 else_block, body_block, is_comptime));
50854111 }
50864112
5087 ir_set_cursor_at_end(irb, body_block);
4113 ir_set_cursor_at_end_and_append_block(irb, body_block);
50884114 if (var_symbol) {
50894115 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node,
50904116 err_val_ptr, false);
......@@ -5111,7 +4137,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
51114137 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime));
51124138
51134139 if (continue_expr_node) {
5114 ir_set_cursor_at_end(irb, continue_block);
4140 ir_set_cursor_at_end_and_append_block(irb, continue_block);
51154141 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope);
51164142 if (expr_result == irb->codegen->invalid_instruction)
51174143 return expr_result;
......@@ -5121,7 +4147,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
51214147
51224148 IrInstruction *else_result = nullptr;
51234149 if (else_node) {
5124 ir_set_cursor_at_end(irb, else_block);
4150 ir_set_cursor_at_end_and_append_block(irb, else_block);
51254151
51264152 // TODO make it an error to write to error variable
51274153 AstNode *err_symbol_node = else_node; // TODO make more accurate
......@@ -5138,7 +4164,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
51384164 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime));
51394165 }
51404166 IrBasicBlock *after_else_block = irb->current_basic_block;
5141 ir_set_cursor_at_end(irb, end_block);
4167 ir_set_cursor_at_end_and_append_block(irb, end_block);
51424168 if (else_result) {
51434169 incoming_blocks.append(after_else_block);
51444170 incoming_values.append(else_result);
......@@ -5149,7 +4175,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
51494175
51504176 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
51514177 } else if (var_symbol != nullptr) {
5152 ir_set_cursor_at_end(irb, cond_block);
4178 ir_set_cursor_at_end_and_append_block(irb, cond_block);
51534179 // TODO make it an error to write to payload variable
51544180 AstNode *symbol_node = node; // TODO make more accurate
51554181 VariableTableEntry *payload_var = ir_create_var(irb, symbol_node, scope, var_symbol,
......@@ -5167,7 +4193,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
51674193 body_block, else_block, is_comptime));
51684194 }
51694195
5170 ir_set_cursor_at_end(irb, body_block);
4196 ir_set_cursor_at_end_and_append_block(irb, body_block);
51714197 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, child_scope, symbol_node, maybe_val_ptr, false);
51724198 IrInstruction *var_value = node->data.while_expr.var_is_ptr ?
51734199 var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value);
......@@ -5191,7 +4217,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
51914217 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
51924218
51934219 if (continue_expr_node) {
5194 ir_set_cursor_at_end(irb, continue_block);
4220 ir_set_cursor_at_end_and_append_block(irb, continue_block);
51954221 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, child_scope);
51964222 if (expr_result == irb->codegen->invalid_instruction)
51974223 return expr_result;
......@@ -5201,7 +4227,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
52014227
52024228 IrInstruction *else_result = nullptr;
52034229 if (else_node) {
5204 ir_set_cursor_at_end(irb, else_block);
4230 ir_set_cursor_at_end_and_append_block(irb, else_block);
52054231
52064232 else_result = ir_gen_node(irb, else_node, scope);
52074233 if (else_result == irb->codegen->invalid_instruction)
......@@ -5210,7 +4236,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
52104236 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime));
52114237 }
52124238 IrBasicBlock *after_else_block = irb->current_basic_block;
5213 ir_set_cursor_at_end(irb, end_block);
4239 ir_set_cursor_at_end_and_append_block(irb, end_block);
52144240 if (else_result) {
52154241 incoming_blocks.append(after_else_block);
52164242 incoming_values.append(else_result);
......@@ -5221,16 +4247,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
52214247
52224248 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
52234249 } else {
5224 if (continue_expr_node) {
5225 ir_set_cursor_at_end(irb, continue_block);
5226 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, scope);
5227 if (expr_result == irb->codegen->invalid_instruction)
5228 return expr_result;
5229 if (!instr_is_unreachable(expr_result))
5230 ir_mark_gen(ir_build_br(irb, scope, node, cond_block, is_comptime));
5231 }
5232
5233 ir_set_cursor_at_end(irb, cond_block);
4250 ir_set_cursor_at_end_and_append_block(irb, cond_block);
52344251 IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope);
52354252 if (cond_val == irb->codegen->invalid_instruction)
52364253 return cond_val;
......@@ -5241,7 +4258,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
52414258 body_block, else_block, is_comptime));
52424259 }
52434260
5244 ir_set_cursor_at_end(irb, body_block);
4261 ir_set_cursor_at_end_and_append_block(irb, body_block);
52454262
52464263 ZigList<IrInstruction *> incoming_values = {0};
52474264 ZigList<IrBasicBlock *> incoming_blocks = {0};
......@@ -5260,9 +4277,18 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
52604277 if (!instr_is_unreachable(body_result))
52614278 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime));
52624279
4280 if (continue_expr_node) {
4281 ir_set_cursor_at_end_and_append_block(irb, continue_block);
4282 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, scope);
4283 if (expr_result == irb->codegen->invalid_instruction)
4284 return expr_result;
4285 if (!instr_is_unreachable(expr_result))
4286 ir_mark_gen(ir_build_br(irb, scope, node, cond_block, is_comptime));
4287 }
4288
52634289 IrInstruction *else_result = nullptr;
52644290 if (else_node) {
5265 ir_set_cursor_at_end(irb, else_block);
4291 ir_set_cursor_at_end_and_append_block(irb, else_block);
52664292
52674293 else_result = ir_gen_node(irb, else_node, scope);
52684294 if (else_result == irb->codegen->invalid_instruction)
......@@ -5271,7 +4297,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n
52714297 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime));
52724298 }
52734299 IrBasicBlock *after_else_block = irb->current_basic_block;
5274 ir_set_cursor_at_end(irb, end_block);
4300 ir_set_cursor_at_end_and_append_block(irb, end_block);
52754301 if (else_result) {
52764302 incoming_blocks.append(after_else_block);
52774303 incoming_values.append(else_result);
......@@ -5344,23 +4370,23 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
53444370 IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var, false, false);
53454371
53464372
5347 IrBasicBlock *cond_block = ir_build_basic_block(irb, child_scope, "ForCond");
5348 IrBasicBlock *body_block = ir_build_basic_block(irb, child_scope, "ForBody");
5349 IrBasicBlock *end_block = ir_build_basic_block(irb, child_scope, "ForEnd");
5350 IrBasicBlock *else_block = else_node ? ir_build_basic_block(irb, child_scope, "ForElse") : end_block;
5351 IrBasicBlock *continue_block = ir_build_basic_block(irb, child_scope, "ForContinue");
4373 IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond");
4374 IrBasicBlock *body_block = ir_create_basic_block(irb, child_scope, "ForBody");
4375 IrBasicBlock *end_block = ir_create_basic_block(irb, child_scope, "ForEnd");
4376 IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, child_scope, "ForElse") : end_block;
4377 IrBasicBlock *continue_block = ir_create_basic_block(irb, child_scope, "ForContinue");
53524378
53534379 IrInstruction *len_val = ir_build_array_len(irb, child_scope, node, array_val);
53544380 ir_build_br(irb, child_scope, node, cond_block, is_comptime);
53554381
5356 ir_set_cursor_at_end(irb, cond_block);
4382 ir_set_cursor_at_end_and_append_block(irb, cond_block);
53574383 IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr);
53584384 IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
53594385 IrBasicBlock *after_cond_block = irb->current_basic_block;
53604386 IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node));
53614387 ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime));
53624388
5363 ir_set_cursor_at_end(irb, body_block);
4389 ir_set_cursor_at_end_and_append_block(irb, body_block);
53644390 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false);
53654391 IrInstruction *elem_val;
53664392 if (node->data.for_expr.elem_is_ptr) {
......@@ -5384,14 +4410,14 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
53844410 if (!instr_is_unreachable(body_result))
53854411 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime));
53864412
5387 ir_set_cursor_at_end(irb, continue_block);
4413 ir_set_cursor_at_end_and_append_block(irb, continue_block);
53884414 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false);
53894415 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val));
53904416 ir_build_br(irb, child_scope, node, cond_block, is_comptime);
53914417
53924418 IrInstruction *else_result = nullptr;
53934419 if (else_node) {
5394 ir_set_cursor_at_end(irb, else_block);
4420 ir_set_cursor_at_end_and_append_block(irb, else_block);
53954421
53964422 else_result = ir_gen_node(irb, else_node, parent_scope);
53974423 if (else_result == irb->codegen->invalid_instruction)
......@@ -5400,7 +4426,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo
54004426 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime));
54014427 }
54024428 IrBasicBlock *after_else_block = irb->current_basic_block;
5403 ir_set_cursor_at_end(irb, end_block);
4429 ir_set_cursor_at_end_and_append_block(irb, end_block);
54044430
54054431 if (else_result) {
54064432 incoming_blocks.append(after_else_block);
......@@ -5577,9 +4603,9 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no
55774603 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr);
55784604 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_val);
55794605
5580 IrBasicBlock *then_block = ir_build_basic_block(irb, scope, "MaybeThen");
5581 IrBasicBlock *else_block = ir_build_basic_block(irb, scope, "MaybeElse");
5582 IrBasicBlock *endif_block = ir_build_basic_block(irb, scope, "MaybeEndIf");
4606 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "MaybeThen");
4607 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "MaybeElse");
4608 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "MaybeEndIf");
55834609
55844610 IrInstruction *is_comptime;
55854611 if (ir_should_inline(irb->exec, scope)) {
......@@ -5589,7 +4615,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no
55894615 }
55904616 ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime);
55914617
5592 ir_set_cursor_at_end(irb, then_block);
4618 ir_set_cursor_at_end_and_append_block(irb, then_block);
55934619
55944620 Scope *var_scope;
55954621 if (var_symbol) {
......@@ -5613,7 +4639,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no
56134639 if (!instr_is_unreachable(then_expr_result))
56144640 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
56154641
5616 ir_set_cursor_at_end(irb, else_block);
4642 ir_set_cursor_at_end_and_append_block(irb, else_block);
56174643 IrInstruction *else_expr_result;
56184644 if (else_node) {
56194645 else_expr_result = ir_gen_node(irb, else_node, scope);
......@@ -5626,7 +4652,7 @@ static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *no
56264652 if (!instr_is_unreachable(else_expr_result))
56274653 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
56284654
5629 ir_set_cursor_at_end(irb, endif_block);
4655 ir_set_cursor_at_end_and_append_block(irb, endif_block);
56304656 IrInstruction **incoming_values = allocate<IrInstruction *>(2);
56314657 incoming_values[0] = then_expr_result;
56324658 incoming_values[1] = else_expr_result;
......@@ -5655,9 +4681,9 @@ static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *nod
56554681 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr);
56564682 IrInstruction *is_err = ir_build_test_err(irb, scope, node, err_val);
56574683
5658 IrBasicBlock *ok_block = ir_build_basic_block(irb, scope, "TryOk");
5659 IrBasicBlock *else_block = ir_build_basic_block(irb, scope, "TryElse");
5660 IrBasicBlock *endif_block = ir_build_basic_block(irb, scope, "TryEnd");
4684 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk");
4685 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse");
4686 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "TryEnd");
56614687
56624688 IrInstruction *is_comptime;
56634689 if (ir_should_inline(irb->exec, scope)) {
......@@ -5667,7 +4693,7 @@ static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *nod
56674693 }
56684694 ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime);
56694695
5670 ir_set_cursor_at_end(irb, ok_block);
4696 ir_set_cursor_at_end_and_append_block(irb, ok_block);
56714697
56724698 Scope *var_scope;
56734699 if (var_symbol) {
......@@ -5690,7 +4716,7 @@ static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *nod
56904716 if (!instr_is_unreachable(then_expr_result))
56914717 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
56924718
5693 ir_set_cursor_at_end(irb, else_block);
4719 ir_set_cursor_at_end_and_append_block(irb, else_block);
56944720
56954721 IrInstruction *else_expr_result;
56964722 if (else_node) {
......@@ -5718,7 +4744,7 @@ static IrInstruction *ir_gen_try_expr(IrBuilder *irb, Scope *scope, AstNode *nod
57184744 if (!instr_is_unreachable(else_expr_result))
57194745 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime));
57204746
5721 ir_set_cursor_at_end(irb, endif_block);
4747 ir_set_cursor_at_end_and_append_block(irb, endif_block);
57224748 IrInstruction **incoming_values = allocate<IrInstruction *>(2);
57234749 incoming_values[0] = then_expr_result;
57244750 incoming_values[1] = else_expr_result;
......@@ -5781,8 +4807,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
57814807 return target_value_ptr;
57824808 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr);
57834809
5784 IrBasicBlock *else_block = ir_build_basic_block(irb, scope, "SwitchElse");
5785 IrBasicBlock *end_block = ir_build_basic_block(irb, scope, "SwitchEnd");
4810 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "SwitchElse");
4811 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "SwitchEnd");
57864812
57874813 size_t prong_count = node->data.switch_expr.prongs.length;
57884814 ZigList<IrInstructionSwitchBrCase> cases = {0};
......@@ -5798,6 +4824,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
57984824 ZigList<IrBasicBlock *> incoming_blocks = {0};
57994825 ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0};
58004826
4827 // First do the else and the ranges
58014828 Scope *comptime_scope = create_comptime_scope(node, scope);
58024829 AstNode *else_prong = nullptr;
58034830 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {
......@@ -5814,90 +4841,47 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
58144841 else_prong = prong_node;
58154842
58164843 IrBasicBlock *prev_block = irb->current_basic_block;
5817 ir_set_cursor_at_end(irb, else_block);
4844 ir_set_cursor_at_end_and_append_block(irb, else_block);
58184845 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
58194846 is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))
58204847 {
58214848 return irb->codegen->invalid_instruction;
58224849 }
58234850 ir_set_cursor_at_end(irb, prev_block);
5824 } else {
5825 if (prong_node->data.switch_prong.any_items_are_range) {
5826 IrInstruction *ok_bit = nullptr;
5827 AstNode *last_item_node = nullptr;
5828 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
5829 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
5830 last_item_node = item_node;
5831 if (item_node->type == NodeTypeSwitchRange) {
5832 AstNode *start_node = item_node->data.switch_range.start;
5833 AstNode *end_node = item_node->data.switch_range.end;
5834
5835 IrInstruction *start_value = ir_gen_node(irb, start_node, comptime_scope);
5836 if (start_value == irb->codegen->invalid_instruction)
5837 return irb->codegen->invalid_instruction;
5838
5839 IrInstruction *end_value = ir_gen_node(irb, end_node, comptime_scope);
5840 if (end_value == irb->codegen->invalid_instruction)
5841 return irb->codegen->invalid_instruction;
5842
5843 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one();
5844 check_range->start = start_value;
5845 check_range->end = end_value;
5846
5847 IrInstruction *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq,
5848 target_value, start_value, false);
5849 IrInstruction *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq,
5850 target_value, end_value, false);
5851 IrInstruction *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd,
5852 lower_range_ok, upper_range_ok, false);
5853 if (ok_bit) {
5854 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false);
5855 } else {
5856 ok_bit = both_ok;
5857 }
5858 } else {
5859 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope);
5860 if (item_value == irb->codegen->invalid_instruction)
5861 return irb->codegen->invalid_instruction;
5862
5863 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one();
5864 check_range->start = item_value;
5865 check_range->end = item_value;
5866
5867 IrInstruction *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq,
5868 item_value, target_value, false);
5869 if (ok_bit) {
5870 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false);
5871 } else {
5872 ok_bit = cmp_ok;
5873 }
5874 }
5875 }
5876
5877 IrBasicBlock *range_block_yes = ir_build_basic_block(irb, scope, "SwitchRangeYes");
5878 IrBasicBlock *range_block_no = ir_build_basic_block(irb, scope, "SwitchRangeNo");
5879
5880 assert(ok_bit);
5881 assert(last_item_node);
5882 ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes,
5883 range_block_no, is_comptime));
5884
5885 ir_set_cursor_at_end(irb, range_block_yes);
5886 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
5887 is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))
5888 {
5889 return irb->codegen->invalid_instruction;
5890 }
5891
5892 ir_set_cursor_at_end(irb, range_block_no);
5893 } else {
5894 IrBasicBlock *prong_block = ir_build_basic_block(irb, scope, "SwitchProng");
5895 IrInstruction *last_item_value = nullptr;
4851 } else if (prong_node->data.switch_prong.any_items_are_range) {
4852 IrInstruction *ok_bit = nullptr;
4853 AstNode *last_item_node = nullptr;
4854 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
4855 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
4856 last_item_node = item_node;
4857 if (item_node->type == NodeTypeSwitchRange) {
4858 AstNode *start_node = item_node->data.switch_range.start;
4859 AstNode *end_node = item_node->data.switch_range.end;
4860
4861 IrInstruction *start_value = ir_gen_node(irb, start_node, comptime_scope);
4862 if (start_value == irb->codegen->invalid_instruction)
4863 return irb->codegen->invalid_instruction;
58964864
5897 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
5898 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
5899 assert(item_node->type != NodeTypeSwitchRange);
4865 IrInstruction *end_value = ir_gen_node(irb, end_node, comptime_scope);
4866 if (end_value == irb->codegen->invalid_instruction)
4867 return irb->codegen->invalid_instruction;
59004868
4869 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one();
4870 check_range->start = start_value;
4871 check_range->end = end_value;
4872
4873 IrInstruction *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq,
4874 target_value, start_value, false);
4875 IrInstruction *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq,
4876 target_value, end_value, false);
4877 IrInstruction *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd,
4878 lower_range_ok, upper_range_ok, false);
4879 if (ok_bit) {
4880 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false);
4881 } else {
4882 ok_bit = both_ok;
4883 }
4884 } else {
59014885 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope);
59024886 if (item_value == irb->codegen->invalid_instruction)
59034887 return irb->codegen->invalid_instruction;
......@@ -5906,26 +4890,77 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
59064890 check_range->start = item_value;
59074891 check_range->end = item_value;
59084892
5909 IrInstructionSwitchBrCase *this_case = cases.add_one();
5910 this_case->value = item_value;
5911 this_case->block = prong_block;
5912
5913 last_item_value = item_value;
4893 IrInstruction *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq,
4894 item_value, target_value, false);
4895 if (ok_bit) {
4896 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false);
4897 } else {
4898 ok_bit = cmp_ok;
4899 }
59144900 }
5915 IrInstruction *only_item_value = (prong_item_count == 1) ? last_item_value : nullptr;
4901 }
59164902
5917 IrBasicBlock *prev_block = irb->current_basic_block;
5918 ir_set_cursor_at_end(irb, prong_block);
5919 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
5920 is_comptime, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values))
5921 {
5922 return irb->codegen->invalid_instruction;
5923 }
4903 IrBasicBlock *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes");
4904 IrBasicBlock *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo");
59244905
5925 ir_set_cursor_at_end(irb, prev_block);
4906 assert(ok_bit);
4907 assert(last_item_node);
4908 ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes,
4909 range_block_no, is_comptime));
59264910
4911 ir_set_cursor_at_end_and_append_block(irb, range_block_yes);
4912 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
4913 is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values))
4914 {
4915 return irb->codegen->invalid_instruction;
59274916 }
4917
4918 ir_set_cursor_at_end_and_append_block(irb, range_block_no);
4919 }
4920 }
4921
4922 // next do the non-else non-ranges
4923 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {
4924 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
4925 size_t prong_item_count = prong_node->data.switch_prong.items.length;
4926 if (prong_item_count == 0)
4927 continue;
4928 if (prong_node->data.switch_prong.any_items_are_range)
4929 continue;
4930
4931 IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng");
4932 IrInstruction *last_item_value = nullptr;
4933
4934 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
4935 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
4936 assert(item_node->type != NodeTypeSwitchRange);
4937
4938 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope);
4939 if (item_value == irb->codegen->invalid_instruction)
4940 return irb->codegen->invalid_instruction;
4941
4942 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one();
4943 check_range->start = item_value;
4944 check_range->end = item_value;
4945
4946 IrInstructionSwitchBrCase *this_case = cases.add_one();
4947 this_case->value = item_value;
4948 this_case->block = prong_block;
4949
4950 last_item_value = item_value;
4951 }
4952 IrInstruction *only_item_value = (prong_item_count == 1) ? last_item_value : nullptr;
4953
4954 IrBasicBlock *prev_block = irb->current_basic_block;
4955 ir_set_cursor_at_end_and_append_block(irb, prong_block);
4956 if (!ir_gen_switch_prong_expr(irb, scope, node, prong_node, end_block,
4957 is_comptime, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values))
4958 {
4959 return irb->codegen->invalid_instruction;
59284960 }
4961
4962 ir_set_cursor_at_end(irb, prev_block);
4963
59294964 }
59304965
59314966 ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length,
......@@ -5938,11 +4973,11 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
59384973 }
59394974
59404975 if (!else_prong) {
5941 ir_set_cursor_at_end(irb, else_block);
4976 ir_set_cursor_at_end_and_append_block(irb, else_block);
59424977 ir_build_unreachable(irb, scope, node);
59434978 }
59444979
5945 ir_set_cursor_at_end(irb, end_block);
4980 ir_set_cursor_at_end_and_append_block(irb, end_block);
59464981 assert(incoming_blocks.length == incoming_values.length);
59474982 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items);
59484983}
......@@ -6158,12 +5193,12 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN
61585193 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_err);
61595194 }
61605195
6161 IrBasicBlock *ok_block = ir_build_basic_block(irb, parent_scope, "UnwrapErrOk");
6162 IrBasicBlock *err_block = ir_build_basic_block(irb, parent_scope, "UnwrapErrError");
6163 IrBasicBlock *end_block = ir_build_basic_block(irb, parent_scope, "UnwrapErrEnd");
5196 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk");
5197 IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError");
5198 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd");
61645199 ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime);
61655200
6166 ir_set_cursor_at_end(irb, err_block);
5201 ir_set_cursor_at_end_and_append_block(irb, err_block);
61675202 Scope *err_scope;
61685203 if (var_node) {
61695204 assert(var_node->type == NodeTypeSymbol);
......@@ -6187,13 +5222,13 @@ static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstN
61875222 if (!instr_is_unreachable(err_result))
61885223 ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime));
61895224
6190 ir_set_cursor_at_end(irb, ok_block);
5225 ir_set_cursor_at_end_and_append_block(irb, ok_block);
61915226 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false);
61925227 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr);
61935228 IrBasicBlock *after_ok_block = irb->current_basic_block;
61945229 ir_build_br(irb, parent_scope, node, end_block, is_comptime);
61955230
6196 ir_set_cursor_at_end(irb, end_block);
5231 ir_set_cursor_at_end_and_append_block(irb, end_block);
61975232 IrInstruction **incoming_values = allocate<IrInstruction *>(2);
61985233 incoming_values[0] = err_result;
61995234 incoming_values[1] = unwrapped_payload;
......@@ -6437,7 +5472,8 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
64375472 irb->codegen = codegen;
64385473 irb->exec = ir_executable;
64395474
6440 irb->current_basic_block = ir_build_basic_block(irb, scope, "Entry");
5475 IrBasicBlock *entry_block = ir_create_basic_block(irb, scope, "Entry");
5476 ir_set_cursor_at_end_and_append_block(irb, entry_block);
64415477 // Entry block gets a reference because we enter it to begin.
64425478 ir_ref_bb(irb->current_basic_block);
64435479
......@@ -7332,6 +6368,7 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira,
73326368 }
73336369 }
73346370
6371
73356372 // implicit number literal to typed number
73366373 // implicit number literal to &const integer
73376374 if (actual_type->id == TypeTableEntryIdNumLitFloat ||
......@@ -7786,32 +6823,14 @@ static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstr
77866823 assert(old_bb);
77876824
77886825 if (old_bb->other) {
7789 if (ref_old_instruction == nullptr || old_bb->other->ref_instruction != ref_old_instruction)
6826 if (ref_old_instruction == nullptr || old_bb->other->ref_instruction != ref_old_instruction) {
77906827 return old_bb->other;
6828 }
77916829 }
77926830
77936831 IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb);
77946832 new_bb->ref_instruction = ref_old_instruction;
77956833
7796 // We are about to enqueue old_bb for analysis. Before we do so, look over old_bb's
7797 // instructions and make sure we have enqueued first the blocks which contain
7798 // instructions old_bb depends on.
7799 for (size_t instr_i = 0; instr_i < old_bb->instruction_list.length; instr_i += 1) {
7800 IrInstruction *instruction = old_bb->instruction_list.at(instr_i);
7801
7802 for (size_t dep_i = 0; ; dep_i += 1) {
7803 IrInstruction *dep_instruction = ir_instruction_get_dep(instruction, dep_i);
7804 if (dep_instruction == nullptr)
7805 break;
7806 if (dep_instruction->other)
7807 continue;
7808 if (dep_instruction->owner_bb == old_bb)
7809 continue;
7810 ir_get_new_bb(ira, dep_instruction->owner_bb, nullptr);
7811 }
7812 }
7813 ira->old_bb_queue.append(old_bb);
7814
78156834 return new_bb;
78166835}
78176836
......@@ -7819,12 +6838,10 @@ static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *cons
78196838 ira->instruction_index = 0;
78206839 ira->old_irb.current_basic_block = old_bb;
78216840 ira->const_predecessor_bb = const_predecessor_bb;
7822
7823 if (!const_predecessor_bb && old_bb->other)
7824 ira->new_irb.exec->basic_block_list.append(old_bb->other);
78256841}
78266842
78276843static void ir_finish_bb(IrAnalyze *ira) {
6844 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block);
78286845 ira->instruction_index += 1;
78296846 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) {
78306847 IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);
......@@ -7835,19 +6852,35 @@ static void ir_finish_bb(IrAnalyze *ira) {
78356852 ira->instruction_index += 1;
78366853 }
78376854
7838 ira->block_queue_index += 1;
6855 ira->old_bb_index += 1;
78396856
7840 if (ira->block_queue_index < ira->old_bb_queue.length) {
7841 IrBasicBlock *old_bb = ira->old_bb_queue.at(ira->block_queue_index);
7842 assert(old_bb->other);
7843 ira->new_irb.current_basic_block = old_bb->other;
6857 bool need_repeat = true;
6858 for (;;) {
6859 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) {
6860 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
6861 if (old_bb->other == nullptr) {
6862 ira->old_bb_index += 1;
6863 continue;
6864 }
6865 if (old_bb->other->instruction_list.length != 0) {
6866 ira->old_bb_index += 1;
6867 continue;
6868 }
6869 ira->new_irb.current_basic_block = old_bb->other;
78446870
7845 ir_start_bb(ira, old_bb, nullptr);
6871 ir_start_bb(ira, old_bb, nullptr);
6872 return;
6873 }
6874 if (!need_repeat)
6875 return;
6876 need_repeat = false;
6877 ira->old_bb_index = 0;
6878 continue;
78466879 }
78476880}
78486881
78496882static TypeTableEntry *ir_unreach_error(IrAnalyze *ira) {
7850 ira->block_queue_index = SIZE_MAX;
6883 ira->old_bb_index = SIZE_MAX;
78516884 ira->new_irb.exec->invalid = true;
78526885 return ira->codegen->builtin_types.entry_unreachable;
78536886}
......@@ -10639,6 +9672,7 @@ static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_nod
106399672static VariableTableEntry *get_fn_var_by_index(FnTableEntry *fn_entry, size_t index) {
106409673 size_t next_var_i = 0;
106419674 FnGenParamInfo *gen_param_info = fn_entry->type_entry->data.fn.gen_param_info;
9675 assert(gen_param_info != nullptr);
106429676 for (size_t param_i = 0; param_i < index; param_i += 1) {
106439677 FnGenParamInfo *info = &gen_param_info[param_i];
106449678 if (info->gen_index == SIZE_MAX)
......@@ -11442,7 +10476,7 @@ static TypeTableEntry *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionP
1144210476 IrInstruction *old_value = phi_instruction->incoming_values[i];
1144310477 assert(old_value);
1144410478 IrInstruction *new_value = old_value->other;
11445 if (!new_value || new_value->value.type->id == TypeTableEntryIdUnreachable)
10479 if (!new_value || new_value->value.type->id == TypeTableEntryIdUnreachable || predecessor->other == nullptr)
1144610480 continue;
1144710481
1144810482 if (type_is_invalid(new_value->value.type))
......@@ -16312,11 +15346,11 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl
1631215346 IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr);
1631315347 ir_ref_bb(new_entry_bb);
1631415348 ira->new_irb.current_basic_block = new_entry_bb;
16315 ira->block_queue_index = 0;
15349 ira->old_bb_index = 0;
1631615350
1631715351 ir_start_bb(ira, old_entry_bb, nullptr);
1631815352
16319 while (ira->block_queue_index < ira->old_bb_queue.length) {
15353 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) {
1632015354 IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index);
1632115355
1632215356 if (old_instruction->ref_count == 0 && !ir_has_side_effects(old_instruction)) {
......@@ -16326,7 +15360,7 @@ TypeTableEntry *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutabl
1632615360
1632715361 TypeTableEntry *return_type = ir_analyze_instruction(ira, old_instruction);
1632815362 if (type_is_invalid(return_type) && ir_should_inline(new_exec, old_instruction->scope)) {
16329 break;
15363 return ira->codegen->builtin_types.entry_invalid;
1633015364 }
1633115365
1633215366 // unreachable instructions do their own control flow.
std/fmt/index.zig+102-1
......@@ -14,6 +14,8 @@ const State = enum { // TODO put inside format function and make sure the name a
1414 CloseBrace,
1515 Integer,
1616 IntegerWidth,
17 Float,
18 FloatWidth,
1719 Character,
1820 Buf,
1921 BufWidth,
......@@ -37,7 +39,6 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
3739 switch (state) {
3840 State.Start => switch (c) {
3941 '{' => {
40 // TODO if you make this an if statement with `and` then it breaks
4142 if (start_index < i) {
4243 %return output(context, fmt[start_index..i]);
4344 }
......@@ -85,6 +86,8 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
8586 },
8687 's' => {
8788 state = State.Buf;
89 },'.' => {
90 state = State.Float;
8891 },
8992 else => @compileError("Unknown format character: " ++ []u8{c}),
9093 },
......@@ -129,6 +132,30 @@ pub fn format(context: var, output: fn(@typeOf(context), []const u8)->%void,
129132 '0' ... '9' => {},
130133 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
131134 },
135 State.Float => switch (c) {
136 '}' => {
137 %return formatFloatDecimal(args[next_arg], 0, context, output);
138 next_arg += 1;
139 state = State.Start;
140 start_index = i + 1;
141 },
142 '0' ... '9' => {
143 width_start = i;
144 state = State.FloatWidth;
145 },
146 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
147 },
148 State.FloatWidth => switch (c) {
149 '}' => {
150 width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10);
151 %return formatFloatDecimal(args[next_arg], width, context, output);
152 next_arg += 1;
153 state = State.Start;
154 start_index = i + 1;
155 },
156 '0' ... '9' => {},
157 else => @compileError("Unexpected character in format string: " ++ []u8{c}),
158 },
132159 State.BufWidth => switch (c) {
133160 '}' => {
134161 width = comptime %%parseUnsigned(usize, fmt[width_start..i], 10);
......@@ -267,6 +294,47 @@ pub fn formatFloat(value: var, context: var, output: fn(@typeOf(context), []cons
267294 }
268295}
269296
297pub fn formatFloatDecimal(value: var, precision: usize, context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void {
298 var x = f64(value);
299
300 // Errol doesn't handle these special cases.
301 if (math.isNan(x)) {
302 return output(context, "NaN");
303 }
304 if (math.signbit(x)) {
305 %return output(context, "-");
306 x = -x;
307 }
308 if (math.isPositiveInf(x)) {
309 return output(context, "Infinity");
310 }
311 if (x == 0.0) {
312 return output(context, "0.0");
313 }
314
315 var buffer: [32]u8 = undefined;
316 const float_decimal = errol3(x, buffer[0..]);
317
318 const num_left_digits = if (float_decimal.exp > 0) usize(float_decimal.exp) else 1;
319
320 %return output(context, float_decimal.digits[0 .. num_left_digits]);
321 %return output(context, ".");
322 if (float_decimal.digits.len > 1) {
323 const num_valid_digtis = if (@typeOf(value) == f32) math.min(usize(7), float_decimal.digits.len)
324 else
325 float_decimal.digits.len;
326
327 const num_right_digits = if (precision != 0)
328 math.min(precision, (num_valid_digtis-num_left_digits))
329 else
330 num_valid_digtis - num_left_digits;
331 %return output(context, float_decimal.digits[num_left_digits .. (num_left_digits + num_right_digits)]);
332 } else {
333 %return output(context, "0");
334 }
335}
336
337
270338pub fn formatInt(value: var, base: u8, uppercase: bool, width: usize,
271339 context: var, output: fn(@typeOf(context), []const u8)->%void) -> %void
272340{
......@@ -540,6 +608,39 @@ test "fmt.format" {
540608 const result = %%bufPrint(buf1[0..], "f64: {}\n", -math.inf_f64);
541609 assert(mem.eql(u8, result, "f64: -Infinity\n"));
542610 }
611 {
612 var buf1: [32]u8 = undefined;
613 const value: f32 = 1.1234;
614 const result = %%bufPrint(buf1[0..], "f32: {.1}\n", value);
615 assert(mem.eql(u8, result, "f32: 1.1\n"));
616 }
617 {
618 var buf1: [32]u8 = undefined;
619 const value: f32 = 1234.567;
620 const result = %%bufPrint(buf1[0..], "f32: {.2}\n", value);
621 assert(mem.eql(u8, result, "f32: 1234.56\n"));
622 }
623 {
624 var buf1: [32]u8 = undefined;
625 const value: f32 = -11.1234;
626 const result = %%bufPrint(buf1[0..], "f32: {.4}\n", value);
627 // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
628 // -11.12339... is truncated to -11.1233
629 assert(mem.eql(u8, result, "f32: -11.1233\n"));
630 }
631 {
632 var buf1: [32]u8 = undefined;
633 const value: f32 = 91.12345;
634 const result = %%bufPrint(buf1[0..], "f32: {.}\n", value);
635 assert(mem.eql(u8, result, "f32: 91.12345\n"));
636 }
637 {
638 var buf1: [32]u8 = undefined;
639 const value: f64 = 91.12345678901235;
640 const result = %%bufPrint(buf1[0..], "f64: {.10}\n", value);
641 assert(mem.eql(u8, result, "f64: 91.1234567890\n"));
642 }
643
543644 }
544645}
545646
std/index.zig+2
......@@ -25,6 +25,7 @@ pub const net = @import("net.zig");
2525pub const os = @import("os/index.zig");
2626pub const rand = @import("rand.zig");
2727pub const sort = @import("sort.zig");
28pub const unicode = @import("unicode.zig");
2829
2930test "std" {
3031 // run tests from these
......@@ -53,4 +54,5 @@ test "std" {
5354 _ = @import("os/index.zig");
5455 _ = @import("rand.zig");
5556 _ = @import("sort.zig");
57 _ = @import("unicode.zig");
5658}
std/io.zig+6-1
......@@ -500,11 +500,16 @@ pub fn writeFile(path: []const u8, data: []const u8, allocator: ?&mem.Allocator)
500500
501501/// On success, caller owns returned buffer.
502502pub fn readFileAlloc(path: []const u8, allocator: &mem.Allocator) -> %[]u8 {
503 return readFileAllocExtra(path, allocator, 0);
504}
505/// On success, caller owns returned buffer.
506/// Allocates extra_len extra bytes at the end of the file buffer, which are uninitialized.
507pub fn readFileAllocExtra(path: []const u8, allocator: &mem.Allocator, extra_len: usize) -> %[]u8 {
503508 var file = %return File.openRead(path, allocator);
504509 defer file.close();
505510
506511 const size = %return file.getEndPos();
507 const buf = %return allocator.alloc(u8, size);
512 const buf = %return allocator.alloc(u8, size + extra_len);
508513 %defer allocator.free(buf);
509514
510515 var adapter = FileInStream.init(&file);
std/math/acos.zig+1-1
......@@ -39,7 +39,7 @@ fn acos32(x: f32) -> f32 {
3939 if (hx >> 31 != 0) {
4040 return 2.0 * pio2_hi + 0x1.0p-120;
4141 } else {
42 return 0;
42 return 0.0;
4343 }
4444 } else {
4545 return math.nan(f32);
std/unicode.zig created+169
......@@ -0,0 +1,169 @@
1const std = @import("./index.zig");
2
3error Utf8InvalidStartByte;
4
5/// Given the first byte of a UTF-8 codepoint,
6/// returns a number 1-4 indicating the total length of the codepoint in bytes.
7/// If this byte does not match the form of a UTF-8 start byte, returns Utf8InvalidStartByte.
8pub fn utf8ByteSequenceLength(first_byte: u8) -> %u3 {
9 if (first_byte < 0b10000000) return u3(1);
10 if (first_byte & 0b11100000 == 0b11000000) return u3(2);
11 if (first_byte & 0b11110000 == 0b11100000) return u3(3);
12 if (first_byte & 0b11111000 == 0b11110000) return u3(4);
13 return error.Utf8InvalidStartByte;
14}
15
16error Utf8OverlongEncoding;
17error Utf8ExpectedContinuation;
18error Utf8EncodesSurrogateHalf;
19error Utf8CodepointTooLarge;
20
21/// Decodes the UTF-8 codepoint encoded in the given slice of bytes.
22/// bytes.len must be equal to %%utf8ByteSequenceLength(bytes[0]).
23/// If you already know the length at comptime, you can call one of
24/// utf8Decode2,utf8Decode3,utf8Decode4 directly instead of this function.
25pub fn utf8Decode(bytes: []const u8) -> %u32 {
26 return switch (bytes.len) {
27 1 => u32(bytes[0]),
28 2 => utf8Decode2(bytes),
29 3 => utf8Decode3(bytes),
30 4 => utf8Decode4(bytes),
31 else => unreachable,
32 };
33}
34pub fn utf8Decode2(bytes: []const u8) -> %u32 {
35 std.debug.assert(bytes.len == 2);
36 std.debug.assert(bytes[0] & 0b11100000 == 0b11000000);
37 var value: u32 = bytes[0] & 0b00011111;
38
39 if (bytes[1] & 0b11000000 != 0b10000000) return error.Utf8ExpectedContinuation;
40 value <<= 6;
41 value |= bytes[1] & 0b00111111;
42
43 if (value < 0x80) return error.Utf8OverlongEncoding;
44
45 return value;
46}
47pub fn utf8Decode3(bytes: []const u8) -> %u32 {
48 std.debug.assert(bytes.len == 3);
49 std.debug.assert(bytes[0] & 0b11110000 == 0b11100000);
50 var value: u32 = bytes[0] & 0b00001111;
51
52 if (bytes[1] & 0b11000000 != 0b10000000) return error.Utf8ExpectedContinuation;
53 value <<= 6;
54 value |= bytes[1] & 0b00111111;
55
56 if (bytes[2] & 0b11000000 != 0b10000000) return error.Utf8ExpectedContinuation;
57 value <<= 6;
58 value |= bytes[2] & 0b00111111;
59
60 if (value < 0x800) return error.Utf8OverlongEncoding;
61 if (0xd800 <= value and value <= 0xdfff) return error.Utf8EncodesSurrogateHalf;
62
63 return value;
64}
65pub fn utf8Decode4(bytes: []const u8) -> %u32 {
66 std.debug.assert(bytes.len == 4);
67 std.debug.assert(bytes[0] & 0b11111000 == 0b11110000);
68 var value: u32 = bytes[0] & 0b00000111;
69
70 if (bytes[1] & 0b11000000 != 0b10000000) return error.Utf8ExpectedContinuation;
71 value <<= 6;
72 value |= bytes[1] & 0b00111111;
73
74 if (bytes[2] & 0b11000000 != 0b10000000) return error.Utf8ExpectedContinuation;
75 value <<= 6;
76 value |= bytes[2] & 0b00111111;
77
78 if (bytes[3] & 0b11000000 != 0b10000000) return error.Utf8ExpectedContinuation;
79 value <<= 6;
80 value |= bytes[3] & 0b00111111;
81
82 if (value < 0x10000) return error.Utf8OverlongEncoding;
83 if (value > 0x10FFFF) return error.Utf8CodepointTooLarge;
84
85 return value;
86}
87
88error UnexpectedEof;
89test "valid utf8" {
90 testValid("\x00", 0x0);
91 testValid("\x20", 0x20);
92 testValid("\x7f", 0x7f);
93 testValid("\xc2\x80", 0x80);
94 testValid("\xdf\xbf", 0x7ff);
95 testValid("\xe0\xa0\x80", 0x800);
96 testValid("\xe1\x80\x80", 0x1000);
97 testValid("\xef\xbf\xbf", 0xffff);
98 testValid("\xf0\x90\x80\x80", 0x10000);
99 testValid("\xf1\x80\x80\x80", 0x40000);
100 testValid("\xf3\xbf\xbf\xbf", 0xfffff);
101 testValid("\xf4\x8f\xbf\xbf", 0x10ffff);
102}
103
104test "invalid utf8 continuation bytes" {
105 // unexpected continuation
106 testError("\x80", error.Utf8InvalidStartByte);
107 testError("\xbf", error.Utf8InvalidStartByte);
108 // too many leading 1's
109 testError("\xf8", error.Utf8InvalidStartByte);
110 testError("\xff", error.Utf8InvalidStartByte);
111 // expected continuation for 2 byte sequences
112 testError("\xc2", error.UnexpectedEof);
113 testError("\xc2\x00", error.Utf8ExpectedContinuation);
114 testError("\xc2\xc0", error.Utf8ExpectedContinuation);
115 // expected continuation for 3 byte sequences
116 testError("\xe0", error.UnexpectedEof);
117 testError("\xe0\x00", error.UnexpectedEof);
118 testError("\xe0\xc0", error.UnexpectedEof);
119 testError("\xe0\xa0", error.UnexpectedEof);
120 testError("\xe0\xa0\x00", error.Utf8ExpectedContinuation);
121 testError("\xe0\xa0\xc0", error.Utf8ExpectedContinuation);
122 // expected continuation for 4 byte sequences
123 testError("\xf0", error.UnexpectedEof);
124 testError("\xf0\x00", error.UnexpectedEof);
125 testError("\xf0\xc0", error.UnexpectedEof);
126 testError("\xf0\x90\x00", error.UnexpectedEof);
127 testError("\xf0\x90\xc0", error.UnexpectedEof);
128 testError("\xf0\x90\x80\x00", error.Utf8ExpectedContinuation);
129 testError("\xf0\x90\x80\xc0", error.Utf8ExpectedContinuation);
130}
131
132test "overlong utf8 codepoint" {
133 testError("\xc0\x80", error.Utf8OverlongEncoding);
134 testError("\xc1\xbf", error.Utf8OverlongEncoding);
135 testError("\xe0\x80\x80", error.Utf8OverlongEncoding);
136 testError("\xe0\x9f\xbf", error.Utf8OverlongEncoding);
137 testError("\xf0\x80\x80\x80", error.Utf8OverlongEncoding);
138 testError("\xf0\x8f\xbf\xbf", error.Utf8OverlongEncoding);
139}
140
141test "misc invalid utf8" {
142 // codepoint out of bounds
143 testError("\xf4\x90\x80\x80", error.Utf8CodepointTooLarge);
144 testError("\xf7\xbf\xbf\xbf", error.Utf8CodepointTooLarge);
145 // surrogate halves
146 testValid("\xed\x9f\xbf", 0xd7ff);
147 testError("\xed\xa0\x80", error.Utf8EncodesSurrogateHalf);
148 testError("\xed\xbf\xbf", error.Utf8EncodesSurrogateHalf);
149 testValid("\xee\x80\x80", 0xe000);
150}
151
152fn testError(bytes: []const u8, expected_err: error) {
153 if (testDecode(bytes)) |_| {
154 unreachable;
155 } else |err| {
156 std.debug.assert(err == expected_err);
157 }
158}
159
160fn testValid(bytes: []const u8, expected_codepoint: u32) {
161 std.debug.assert(%%testDecode(bytes) == expected_codepoint);
162}
163
164fn testDecode(bytes: []const u8) -> %u32 {
165 const length = %return utf8ByteSequenceLength(bytes[0]);
166 if (bytes.len < length) return error.UnexpectedEof;
167 std.debug.assert(bytes.len == length);
168 return utf8Decode(bytes);
169}
test/cases/cast.zig+9-8
......@@ -230,20 +230,21 @@ fn foo(args: ...) {
230230
231231
232232test "peer type resolution: error and [N]T" {
233 assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
234 comptime assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
233 // TODO: implicit %T to %U where T can implicitly cast to U
234 //assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
235 //comptime assert(mem.eql(u8, %%testPeerErrorAndArray(0), "OK"));
235236
236237 assert(mem.eql(u8, %%testPeerErrorAndArray2(1), "OKK"));
237238 comptime assert(mem.eql(u8, %%testPeerErrorAndArray2(1), "OKK"));
238239}
239240
240241error BadValue;
241fn testPeerErrorAndArray(x: u8) -> %[]const u8 {
242 return switch (x) {
243 0x00 => "OK",
244 else => error.BadValue,
245 };
246}
242//fn testPeerErrorAndArray(x: u8) -> %[]const u8 {
243// return switch (x) {
244// 0x00 => "OK",
245// else => error.BadValue,
246// };
247//}
247248fn testPeerErrorAndArray2(x: u8) -> %[]const u8 {
248249 return switch (x) {
249250 0x00 => "OK",
test/cases/misc.zig+11
......@@ -560,3 +560,14 @@ fn hereIsAnOpaqueType(ptr: &OpaqueA) -> &OpaqueA {
560560 var a = ptr;
561561 return a;
562562}
563
564test "comptime if inside runtime while which unconditionally breaks" {
565 testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
566 comptime testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(true);
567}
568fn testComptimeIfInsideRuntimeWhileWhichUnconditionallyBreaks(cond: bool) {
569 while (cond) {
570 if (false) { }
571 break;
572 }
573}