1 /*
2  * Copyright (c) 2021 Andrew Kelley
3  *
4  * This file is part of zig, which is MIT licensed.
5  * See http://opensource.org/licenses/MIT
6  */
7 
8 #include "astgen.hpp"
9 #include "analyze.hpp"
10 #include "util.hpp"
11 #include "os.hpp"
12 #include "parser.hpp"
13 
14 struct Stage1AstGen {
15     CodeGen *codegen;
16     Stage1Zir *exec;
17     Stage1ZirBasicBlock *current_basic_block;
18     AstNode *main_block_node;
19     size_t next_debug_id;
20     ZigFn *fn;
21     bool in_c_import_scope;
22 };
23 
24 static Stage1ZirInst *astgen_node(Stage1AstGen *ag, AstNode *node, Scope *scope);
25 static Stage1ZirInst *astgen_node_extra(Stage1AstGen *ag, AstNode *node, Scope *scope, LVal lval,
26         ResultLoc *result_loc);
27 
28 static Stage1ZirInst *ir_lval_wrap(Stage1AstGen *ag, Scope *scope, Stage1ZirInst *value, LVal lval,
29         ResultLoc *result_loc);
30 static Stage1ZirInst *ir_expr_wrap(Stage1AstGen *ag, Scope *scope, Stage1ZirInst *inst,
31         ResultLoc *result_loc);
32 static Stage1ZirInst *astgen_union_init_expr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
33     Stage1ZirInst *union_type, Stage1ZirInst *field_name, AstNode *expr_node,
34     LVal lval, ResultLoc *parent_result_loc);
35 static ResultLocCast *ir_build_cast_result_loc(Stage1AstGen *ag, Stage1ZirInst *dest_type,
36         ResultLoc *parent_result_loc);
37 static ZigVar *ir_create_var(Stage1AstGen *ag, AstNode *node, Scope *scope, Buf *name,
38         bool src_is_const, bool gen_is_const, bool is_shadowable, Stage1ZirInst *is_comptime);
39 static void build_decl_var_and_init(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
40         ZigVar *var, Stage1ZirInst *init, const char *name_hint, Stage1ZirInst *is_comptime);
41 
ir_assert_impl(bool ok,Stage1ZirInst * source_instruction,char const * file,unsigned int line)42 static void ir_assert_impl(bool ok, Stage1ZirInst *source_instruction, char const *file, unsigned int line) {
43     if (ok) return;
44     src_assert_impl(ok, source_instruction->source_node, file, line);
45 }
46 
exec_add_error_node(CodeGen * codegen,Stage1Zir * exec,AstNode * source_node,Buf * msg)47 static ErrorMsg *exec_add_error_node(CodeGen *codegen, Stage1Zir *exec, AstNode *source_node, Buf *msg) {
48     ErrorMsg *err_msg = add_node_error(codegen, source_node, msg);
49     invalidate_exec(exec, err_msg);
50     return err_msg;
51 }
52 
53 
54 #define ir_assert(OK, SOURCE_INSTRUCTION) ir_assert_impl((OK), (SOURCE_INSTRUCTION), __FILE__, __LINE__)
55 
56 
instr_is_unreachable(Stage1ZirInst * instruction)57 static bool instr_is_unreachable(Stage1ZirInst *instruction) {
58     switch (instruction->id) {
59         case Stage1ZirInstIdCondBr:
60         case Stage1ZirInstIdReturn:
61         case Stage1ZirInstIdBr:
62         case Stage1ZirInstIdUnreachable:
63         case Stage1ZirInstIdSwitchBr:
64         case Stage1ZirInstIdPanic:
65             return true;
66         default:
67             return false;
68     }
69 }
70 
destroy_instruction_src(Stage1ZirInst * inst)71 void destroy_instruction_src(Stage1ZirInst *inst) {
72     switch (inst->id) {
73         case Stage1ZirInstIdInvalid:
74             zig_unreachable();
75         case Stage1ZirInstIdReturn:
76             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstReturn *>(inst));
77         case Stage1ZirInstIdConst:
78             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstConst *>(inst));
79         case Stage1ZirInstIdBinOp:
80             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstBinOp *>(inst));
81         case Stage1ZirInstIdMergeErrSets:
82             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstMergeErrSets *>(inst));
83         case Stage1ZirInstIdDeclVar:
84             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstDeclVar *>(inst));
85         case Stage1ZirInstIdCall:
86             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCall *>(inst));
87         case Stage1ZirInstIdCallExtra:
88             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCallExtra *>(inst));
89         case Stage1ZirInstIdAsyncCallExtra:
90             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAsyncCallExtra *>(inst));
91         case Stage1ZirInstIdUnOp:
92             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstUnOp *>(inst));
93         case Stage1ZirInstIdCondBr:
94             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCondBr *>(inst));
95         case Stage1ZirInstIdBr:
96             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstBr *>(inst));
97         case Stage1ZirInstIdPhi:
98             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstPhi *>(inst));
99         case Stage1ZirInstIdContainerInitList:
100             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstContainerInitList *>(inst));
101         case Stage1ZirInstIdContainerInitFields:
102             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstContainerInitFields *>(inst));
103         case Stage1ZirInstIdUnreachable:
104             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstUnreachable *>(inst));
105         case Stage1ZirInstIdElemPtr:
106             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstElemPtr *>(inst));
107         case Stage1ZirInstIdVarPtr:
108             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstVarPtr *>(inst));
109         case Stage1ZirInstIdLoadPtr:
110             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstLoadPtr *>(inst));
111         case Stage1ZirInstIdStorePtr:
112             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstStorePtr *>(inst));
113         case Stage1ZirInstIdTypeOf:
114             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstTypeOf *>(inst));
115         case Stage1ZirInstIdFieldPtr:
116             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstFieldPtr *>(inst));
117         case Stage1ZirInstIdSetCold:
118             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSetCold *>(inst));
119         case Stage1ZirInstIdSetRuntimeSafety:
120             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSetRuntimeSafety *>(inst));
121         case Stage1ZirInstIdSetFloatMode:
122             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSetFloatMode *>(inst));
123         case Stage1ZirInstIdArrayType:
124             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstArrayType *>(inst));
125         case Stage1ZirInstIdSliceType:
126             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSliceType *>(inst));
127         case Stage1ZirInstIdAnyFrameType:
128             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAnyFrameType *>(inst));
129         case Stage1ZirInstIdAsm:
130             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAsm *>(inst));
131         case Stage1ZirInstIdSizeOf:
132             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSizeOf *>(inst));
133         case Stage1ZirInstIdTestNonNull:
134             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstTestNonNull *>(inst));
135         case Stage1ZirInstIdOptionalUnwrapPtr:
136             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstOptionalUnwrapPtr *>(inst));
137         case Stage1ZirInstIdPopCount:
138             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstPopCount *>(inst));
139         case Stage1ZirInstIdClz:
140             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstClz *>(inst));
141         case Stage1ZirInstIdCtz:
142             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCtz *>(inst));
143         case Stage1ZirInstIdBswap:
144             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstBswap *>(inst));
145         case Stage1ZirInstIdBitReverse:
146             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstBitReverse *>(inst));
147         case Stage1ZirInstIdSwitchBr:
148             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSwitchBr *>(inst));
149         case Stage1ZirInstIdSwitchVar:
150             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSwitchVar *>(inst));
151         case Stage1ZirInstIdSwitchElseVar:
152             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSwitchElseVar *>(inst));
153         case Stage1ZirInstIdSwitchTarget:
154             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSwitchTarget *>(inst));
155         case Stage1ZirInstIdImport:
156             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstImport *>(inst));
157         case Stage1ZirInstIdRef:
158             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstRef *>(inst));
159         case Stage1ZirInstIdCompileErr:
160             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCompileErr *>(inst));
161         case Stage1ZirInstIdCompileLog:
162             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCompileLog *>(inst));
163         case Stage1ZirInstIdErrName:
164             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstErrName *>(inst));
165         case Stage1ZirInstIdCImport:
166             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCImport *>(inst));
167         case Stage1ZirInstIdCInclude:
168             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCInclude *>(inst));
169         case Stage1ZirInstIdCDefine:
170             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCDefine *>(inst));
171         case Stage1ZirInstIdCUndef:
172             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCUndef *>(inst));
173         case Stage1ZirInstIdEmbedFile:
174             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstEmbedFile *>(inst));
175         case Stage1ZirInstIdCmpxchg:
176             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCmpxchg *>(inst));
177         case Stage1ZirInstIdFence:
178             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstFence *>(inst));
179         case Stage1ZirInstIdReduce:
180             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstReduce *>(inst));
181         case Stage1ZirInstIdTruncate:
182             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstTruncate *>(inst));
183         case Stage1ZirInstIdIntCast:
184             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstIntCast *>(inst));
185         case Stage1ZirInstIdFloatCast:
186             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstFloatCast *>(inst));
187         case Stage1ZirInstIdErrSetCast:
188             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstErrSetCast *>(inst));
189         case Stage1ZirInstIdIntToFloat:
190             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstIntToFloat *>(inst));
191         case Stage1ZirInstIdFloatToInt:
192             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstFloatToInt *>(inst));
193         case Stage1ZirInstIdBoolToInt:
194             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstBoolToInt *>(inst));
195         case Stage1ZirInstIdVectorType:
196             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstVectorType *>(inst));
197         case Stage1ZirInstIdShuffleVector:
198             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstShuffleVector *>(inst));
199         case Stage1ZirInstIdSelect:
200             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSelect *>(inst));
201         case Stage1ZirInstIdSplat:
202             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSplat *>(inst));
203         case Stage1ZirInstIdBoolNot:
204             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstBoolNot *>(inst));
205         case Stage1ZirInstIdMemset:
206             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstMemset *>(inst));
207         case Stage1ZirInstIdMemcpy:
208             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstMemcpy *>(inst));
209         case Stage1ZirInstIdSlice:
210             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSlice *>(inst));
211         case Stage1ZirInstIdBreakpoint:
212             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstBreakpoint *>(inst));
213         case Stage1ZirInstIdReturnAddress:
214             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstReturnAddress *>(inst));
215         case Stage1ZirInstIdFrameAddress:
216             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstFrameAddress *>(inst));
217         case Stage1ZirInstIdFrameHandle:
218             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstFrameHandle *>(inst));
219         case Stage1ZirInstIdFrameType:
220             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstFrameType *>(inst));
221         case Stage1ZirInstIdFrameSize:
222             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstFrameSize *>(inst));
223         case Stage1ZirInstIdAlignOf:
224             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAlignOf *>(inst));
225         case Stage1ZirInstIdOverflowOp:
226             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstOverflowOp *>(inst));
227         case Stage1ZirInstIdTestErr:
228             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstTestErr *>(inst));
229         case Stage1ZirInstIdUnwrapErrCode:
230             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstUnwrapErrCode *>(inst));
231         case Stage1ZirInstIdUnwrapErrPayload:
232             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstUnwrapErrPayload *>(inst));
233         case Stage1ZirInstIdFnProto:
234             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstFnProto *>(inst));
235         case Stage1ZirInstIdTestComptime:
236             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstTestComptime *>(inst));
237         case Stage1ZirInstIdPtrCast:
238             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstPtrCast *>(inst));
239         case Stage1ZirInstIdBitCast:
240             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstBitCast *>(inst));
241         case Stage1ZirInstIdPtrToInt:
242             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstPtrToInt *>(inst));
243         case Stage1ZirInstIdIntToPtr:
244             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstIntToPtr *>(inst));
245         case Stage1ZirInstIdIntToEnum:
246             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstIntToEnum *>(inst));
247         case Stage1ZirInstIdIntToErr:
248             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstIntToErr *>(inst));
249         case Stage1ZirInstIdErrToInt:
250             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstErrToInt *>(inst));
251         case Stage1ZirInstIdCheckSwitchProngsUnderNo:
252         case Stage1ZirInstIdCheckSwitchProngsUnderYes:
253             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCheckSwitchProngs *>(inst));
254         case Stage1ZirInstIdCheckStatementIsVoid:
255             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCheckStatementIsVoid *>(inst));
256         case Stage1ZirInstIdTypeName:
257             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstTypeName *>(inst));
258         case Stage1ZirInstIdTagName:
259             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstTagName *>(inst));
260         case Stage1ZirInstIdPtrType:
261             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstPtrType *>(inst));
262         case Stage1ZirInstIdPtrTypeSimple:
263         case Stage1ZirInstIdPtrTypeSimpleConst:
264             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstPtrTypeSimple *>(inst));
265         case Stage1ZirInstIdDeclRef:
266             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstDeclRef *>(inst));
267         case Stage1ZirInstIdPanic:
268             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstPanic *>(inst));
269         case Stage1ZirInstIdFieldParentPtr:
270             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstFieldParentPtr *>(inst));
271         case Stage1ZirInstIdOffsetOf:
272             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstOffsetOf *>(inst));
273         case Stage1ZirInstIdBitOffsetOf:
274             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstBitOffsetOf *>(inst));
275         case Stage1ZirInstIdTypeInfo:
276             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstTypeInfo *>(inst));
277         case Stage1ZirInstIdType:
278             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstType *>(inst));
279         case Stage1ZirInstIdHasField:
280             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstHasField *>(inst));
281         case Stage1ZirInstIdSetEvalBranchQuota:
282             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSetEvalBranchQuota *>(inst));
283         case Stage1ZirInstIdAlignCast:
284             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAlignCast *>(inst));
285         case Stage1ZirInstIdImplicitCast:
286             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstImplicitCast *>(inst));
287         case Stage1ZirInstIdResolveResult:
288             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstResolveResult *>(inst));
289         case Stage1ZirInstIdResetResult:
290             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstResetResult *>(inst));
291         case Stage1ZirInstIdSetAlignStack:
292             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSetAlignStack *>(inst));
293         case Stage1ZirInstIdArgTypeAllowVarFalse:
294         case Stage1ZirInstIdArgTypeAllowVarTrue:
295             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstArgType *>(inst));
296         case Stage1ZirInstIdExport:
297             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstExport *>(inst));
298         case Stage1ZirInstIdExtern:
299             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstExtern *>(inst));
300         case Stage1ZirInstIdErrorReturnTrace:
301             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstErrorReturnTrace *>(inst));
302         case Stage1ZirInstIdErrorUnion:
303             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstErrorUnion *>(inst));
304         case Stage1ZirInstIdAtomicRmw:
305             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAtomicRmw *>(inst));
306         case Stage1ZirInstIdSaveErrRetAddr:
307             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSaveErrRetAddr *>(inst));
308         case Stage1ZirInstIdAddImplicitReturnType:
309             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAddImplicitReturnType *>(inst));
310         case Stage1ZirInstIdFloatOp:
311             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstFloatOp *>(inst));
312         case Stage1ZirInstIdMulAdd:
313             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstMulAdd *>(inst));
314         case Stage1ZirInstIdAtomicLoad:
315             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAtomicLoad *>(inst));
316         case Stage1ZirInstIdAtomicStore:
317             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAtomicStore *>(inst));
318         case Stage1ZirInstIdEnumToInt:
319             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstEnumToInt *>(inst));
320         case Stage1ZirInstIdCheckRuntimeScope:
321             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCheckRuntimeScope *>(inst));
322         case Stage1ZirInstIdHasDecl:
323             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstHasDecl *>(inst));
324         case Stage1ZirInstIdUndeclaredIdent:
325             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstUndeclaredIdent *>(inst));
326         case Stage1ZirInstIdAlloca:
327             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAlloca *>(inst));
328         case Stage1ZirInstIdEndExpr:
329             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstEndExpr *>(inst));
330         case Stage1ZirInstIdUnionInitNamedField:
331             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstUnionInitNamedField *>(inst));
332         case Stage1ZirInstIdSuspendBegin:
333             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSuspendBegin *>(inst));
334         case Stage1ZirInstIdSuspendFinish:
335             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSuspendFinish *>(inst));
336         case Stage1ZirInstIdResume:
337             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstResume *>(inst));
338         case Stage1ZirInstIdAwait:
339             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstAwait *>(inst));
340         case Stage1ZirInstIdSpillBegin:
341             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSpillBegin *>(inst));
342         case Stage1ZirInstIdSpillEnd:
343             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSpillEnd *>(inst));
344         case Stage1ZirInstIdCallArgs:
345             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstCallArgs *>(inst));
346         case Stage1ZirInstIdWasmMemorySize:
347             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstWasmMemorySize *>(inst));
348         case Stage1ZirInstIdWasmMemoryGrow:
349             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstWasmMemoryGrow *>(inst));
350         case Stage1ZirInstIdSrc:
351             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstSrc *>(inst));
352         case Stage1ZirInstIdPrefetch:
353             return heap::c_allocator.destroy(reinterpret_cast<Stage1ZirInstPrefetch *>(inst));
354     }
355     zig_unreachable();
356 }
357 
358 
ir_should_inline(Stage1Zir * exec,Scope * scope)359 bool ir_should_inline(Stage1Zir *exec, Scope *scope) {
360     if (exec->is_inline)
361         return true;
362 
363     while (scope != nullptr) {
364         if (scope->id == ScopeIdCompTime)
365             return true;
366         if (scope->id == ScopeIdTypeOf)
367             return false;
368         if (scope->id == ScopeIdFnDef)
369             break;
370         scope = scope->parent;
371     }
372     return false;
373 }
374 
ir_instruction_append(Stage1ZirBasicBlock * basic_block,Stage1ZirInst * instruction)375 static void ir_instruction_append(Stage1ZirBasicBlock *basic_block, Stage1ZirInst *instruction) {
376     assert(basic_block);
377     assert(instruction);
378     basic_block->instruction_list.append(instruction);
379 }
380 
irb_next_debug_id(Stage1AstGen * ag)381 static size_t irb_next_debug_id(Stage1AstGen *ag) {
382     size_t result = ag->next_debug_id;
383     ag->next_debug_id += 1;
384     return result;
385 }
386 
ir_ref_bb(Stage1ZirBasicBlock * bb)387 static void ir_ref_bb(Stage1ZirBasicBlock *bb) {
388     bb->ref_count += 1;
389 }
390 
ir_ref_instruction(Stage1ZirInst * instruction,Stage1ZirBasicBlock * cur_bb)391 static void ir_ref_instruction(Stage1ZirInst *instruction, Stage1ZirBasicBlock *cur_bb) {
392     assert(instruction->id != Stage1ZirInstIdInvalid);
393     instruction->ref_count += 1;
394     if (instruction->owner_bb != cur_bb && !instr_is_unreachable(instruction)
395         && instruction->id != Stage1ZirInstIdConst)
396     {
397         ir_ref_bb(instruction->owner_bb);
398     }
399 }
400 
ir_create_basic_block(Stage1AstGen * ag,Scope * scope,const char * name_hint)401 static Stage1ZirBasicBlock *ir_create_basic_block(Stage1AstGen *ag, Scope *scope, const char *name_hint) {
402     Stage1ZirBasicBlock *result = heap::c_allocator.create<Stage1ZirBasicBlock>();
403     result->scope = scope;
404     result->name_hint = name_hint;
405     result->debug_id = irb_next_debug_id(ag);
406     result->index = UINT32_MAX; // set later
407     return result;
408 }
409 
ir_inst_id(Stage1ZirInstDeclVar *)410 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstDeclVar *) {
411     return Stage1ZirInstIdDeclVar;
412 }
413 
ir_inst_id(Stage1ZirInstBr *)414 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstBr *) {
415     return Stage1ZirInstIdBr;
416 }
417 
ir_inst_id(Stage1ZirInstCondBr *)418 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCondBr *) {
419     return Stage1ZirInstIdCondBr;
420 }
421 
ir_inst_id(Stage1ZirInstSwitchBr *)422 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSwitchBr *) {
423     return Stage1ZirInstIdSwitchBr;
424 }
425 
ir_inst_id(Stage1ZirInstSwitchVar *)426 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSwitchVar *) {
427     return Stage1ZirInstIdSwitchVar;
428 }
429 
ir_inst_id(Stage1ZirInstSwitchElseVar *)430 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSwitchElseVar *) {
431     return Stage1ZirInstIdSwitchElseVar;
432 }
433 
ir_inst_id(Stage1ZirInstSwitchTarget *)434 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSwitchTarget *) {
435     return Stage1ZirInstIdSwitchTarget;
436 }
437 
ir_inst_id(Stage1ZirInstPhi *)438 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPhi *) {
439     return Stage1ZirInstIdPhi;
440 }
441 
ir_inst_id(Stage1ZirInstUnOp *)442 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstUnOp *) {
443     return Stage1ZirInstIdUnOp;
444 }
445 
ir_inst_id(Stage1ZirInstBinOp *)446 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstBinOp *) {
447     return Stage1ZirInstIdBinOp;
448 }
449 
ir_inst_id(Stage1ZirInstMergeErrSets *)450 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstMergeErrSets *) {
451     return Stage1ZirInstIdMergeErrSets;
452 }
453 
ir_inst_id(Stage1ZirInstLoadPtr *)454 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstLoadPtr *) {
455     return Stage1ZirInstIdLoadPtr;
456 }
457 
ir_inst_id(Stage1ZirInstStorePtr *)458 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstStorePtr *) {
459     return Stage1ZirInstIdStorePtr;
460 }
461 
ir_inst_id(Stage1ZirInstFieldPtr *)462 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstFieldPtr *) {
463     return Stage1ZirInstIdFieldPtr;
464 }
465 
ir_inst_id(Stage1ZirInstElemPtr *)466 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstElemPtr *) {
467     return Stage1ZirInstIdElemPtr;
468 }
469 
ir_inst_id(Stage1ZirInstVarPtr *)470 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstVarPtr *) {
471     return Stage1ZirInstIdVarPtr;
472 }
473 
ir_inst_id(Stage1ZirInstCall *)474 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCall *) {
475     return Stage1ZirInstIdCall;
476 }
477 
ir_inst_id(Stage1ZirInstCallArgs *)478 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCallArgs *) {
479     return Stage1ZirInstIdCallArgs;
480 }
481 
ir_inst_id(Stage1ZirInstCallExtra *)482 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCallExtra *) {
483     return Stage1ZirInstIdCallExtra;
484 }
485 
ir_inst_id(Stage1ZirInstAsyncCallExtra *)486 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAsyncCallExtra *) {
487     return Stage1ZirInstIdAsyncCallExtra;
488 }
489 
ir_inst_id(Stage1ZirInstConst *)490 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstConst *) {
491     return Stage1ZirInstIdConst;
492 }
493 
ir_inst_id(Stage1ZirInstReturn *)494 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstReturn *) {
495     return Stage1ZirInstIdReturn;
496 }
497 
ir_inst_id(Stage1ZirInstContainerInitList *)498 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstContainerInitList *) {
499     return Stage1ZirInstIdContainerInitList;
500 }
501 
ir_inst_id(Stage1ZirInstContainerInitFields *)502 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstContainerInitFields *) {
503     return Stage1ZirInstIdContainerInitFields;
504 }
505 
ir_inst_id(Stage1ZirInstUnreachable *)506 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstUnreachable *) {
507     return Stage1ZirInstIdUnreachable;
508 }
509 
ir_inst_id(Stage1ZirInstTypeOf *)510 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstTypeOf *) {
511     return Stage1ZirInstIdTypeOf;
512 }
513 
ir_inst_id(Stage1ZirInstSetCold *)514 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSetCold *) {
515     return Stage1ZirInstIdSetCold;
516 }
517 
ir_inst_id(Stage1ZirInstSetRuntimeSafety *)518 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSetRuntimeSafety *) {
519     return Stage1ZirInstIdSetRuntimeSafety;
520 }
521 
ir_inst_id(Stage1ZirInstSetFloatMode *)522 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSetFloatMode *) {
523     return Stage1ZirInstIdSetFloatMode;
524 }
525 
ir_inst_id(Stage1ZirInstArrayType *)526 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstArrayType *) {
527     return Stage1ZirInstIdArrayType;
528 }
529 
ir_inst_id(Stage1ZirInstAnyFrameType *)530 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAnyFrameType *) {
531     return Stage1ZirInstIdAnyFrameType;
532 }
533 
ir_inst_id(Stage1ZirInstSliceType *)534 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSliceType *) {
535     return Stage1ZirInstIdSliceType;
536 }
537 
ir_inst_id(Stage1ZirInstAsm *)538 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAsm *) {
539     return Stage1ZirInstIdAsm;
540 }
541 
ir_inst_id(Stage1ZirInstSizeOf *)542 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSizeOf *) {
543     return Stage1ZirInstIdSizeOf;
544 }
545 
ir_inst_id(Stage1ZirInstTestNonNull *)546 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstTestNonNull *) {
547     return Stage1ZirInstIdTestNonNull;
548 }
549 
ir_inst_id(Stage1ZirInstOptionalUnwrapPtr *)550 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstOptionalUnwrapPtr *) {
551     return Stage1ZirInstIdOptionalUnwrapPtr;
552 }
553 
ir_inst_id(Stage1ZirInstClz *)554 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstClz *) {
555     return Stage1ZirInstIdClz;
556 }
557 
ir_inst_id(Stage1ZirInstCtz *)558 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCtz *) {
559     return Stage1ZirInstIdCtz;
560 }
561 
ir_inst_id(Stage1ZirInstPopCount *)562 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPopCount *) {
563     return Stage1ZirInstIdPopCount;
564 }
565 
ir_inst_id(Stage1ZirInstBswap *)566 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstBswap *) {
567     return Stage1ZirInstIdBswap;
568 }
569 
ir_inst_id(Stage1ZirInstBitReverse *)570 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstBitReverse *) {
571     return Stage1ZirInstIdBitReverse;
572 }
573 
ir_inst_id(Stage1ZirInstImport *)574 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstImport *) {
575     return Stage1ZirInstIdImport;
576 }
577 
ir_inst_id(Stage1ZirInstCImport *)578 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCImport *) {
579     return Stage1ZirInstIdCImport;
580 }
581 
ir_inst_id(Stage1ZirInstCInclude *)582 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCInclude *) {
583     return Stage1ZirInstIdCInclude;
584 }
585 
ir_inst_id(Stage1ZirInstCDefine *)586 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCDefine *) {
587     return Stage1ZirInstIdCDefine;
588 }
589 
ir_inst_id(Stage1ZirInstCUndef *)590 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCUndef *) {
591     return Stage1ZirInstIdCUndef;
592 }
593 
ir_inst_id(Stage1ZirInstRef *)594 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstRef *) {
595     return Stage1ZirInstIdRef;
596 }
597 
ir_inst_id(Stage1ZirInstCompileErr *)598 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCompileErr *) {
599     return Stage1ZirInstIdCompileErr;
600 }
601 
ir_inst_id(Stage1ZirInstCompileLog *)602 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCompileLog *) {
603     return Stage1ZirInstIdCompileLog;
604 }
605 
ir_inst_id(Stage1ZirInstErrName *)606 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstErrName *) {
607     return Stage1ZirInstIdErrName;
608 }
609 
ir_inst_id(Stage1ZirInstEmbedFile *)610 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstEmbedFile *) {
611     return Stage1ZirInstIdEmbedFile;
612 }
613 
ir_inst_id(Stage1ZirInstCmpxchg *)614 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCmpxchg *) {
615     return Stage1ZirInstIdCmpxchg;
616 }
617 
ir_inst_id(Stage1ZirInstFence *)618 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstFence *) {
619     return Stage1ZirInstIdFence;
620 }
621 
ir_inst_id(Stage1ZirInstReduce *)622 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstReduce *) {
623     return Stage1ZirInstIdReduce;
624 }
625 
ir_inst_id(Stage1ZirInstTruncate *)626 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstTruncate *) {
627     return Stage1ZirInstIdTruncate;
628 }
629 
ir_inst_id(Stage1ZirInstIntCast *)630 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstIntCast *) {
631     return Stage1ZirInstIdIntCast;
632 }
633 
ir_inst_id(Stage1ZirInstFloatCast *)634 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstFloatCast *) {
635     return Stage1ZirInstIdFloatCast;
636 }
637 
ir_inst_id(Stage1ZirInstIntToFloat *)638 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstIntToFloat *) {
639     return Stage1ZirInstIdIntToFloat;
640 }
641 
ir_inst_id(Stage1ZirInstFloatToInt *)642 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstFloatToInt *) {
643     return Stage1ZirInstIdFloatToInt;
644 }
645 
ir_inst_id(Stage1ZirInstBoolToInt *)646 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstBoolToInt *) {
647     return Stage1ZirInstIdBoolToInt;
648 }
649 
ir_inst_id(Stage1ZirInstVectorType *)650 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstVectorType *) {
651     return Stage1ZirInstIdVectorType;
652 }
653 
ir_inst_id(Stage1ZirInstShuffleVector *)654 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstShuffleVector *) {
655     return Stage1ZirInstIdShuffleVector;
656 }
657 
ir_inst_id(Stage1ZirInstSelect *)658 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSelect *) {
659     return Stage1ZirInstIdSelect;
660 }
661 
ir_inst_id(Stage1ZirInstSplat *)662 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSplat *) {
663     return Stage1ZirInstIdSplat;
664 }
665 
ir_inst_id(Stage1ZirInstBoolNot *)666 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstBoolNot *) {
667     return Stage1ZirInstIdBoolNot;
668 }
669 
ir_inst_id(Stage1ZirInstMemset *)670 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstMemset *) {
671     return Stage1ZirInstIdMemset;
672 }
673 
ir_inst_id(Stage1ZirInstMemcpy *)674 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstMemcpy *) {
675     return Stage1ZirInstIdMemcpy;
676 }
677 
ir_inst_id(Stage1ZirInstSlice *)678 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSlice *) {
679     return Stage1ZirInstIdSlice;
680 }
681 
ir_inst_id(Stage1ZirInstBreakpoint *)682 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstBreakpoint *) {
683     return Stage1ZirInstIdBreakpoint;
684 }
685 
ir_inst_id(Stage1ZirInstReturnAddress *)686 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstReturnAddress *) {
687     return Stage1ZirInstIdReturnAddress;
688 }
689 
ir_inst_id(Stage1ZirInstFrameAddress *)690 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstFrameAddress *) {
691     return Stage1ZirInstIdFrameAddress;
692 }
693 
ir_inst_id(Stage1ZirInstFrameHandle *)694 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstFrameHandle *) {
695     return Stage1ZirInstIdFrameHandle;
696 }
697 
ir_inst_id(Stage1ZirInstFrameType *)698 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstFrameType *) {
699     return Stage1ZirInstIdFrameType;
700 }
701 
ir_inst_id(Stage1ZirInstFrameSize *)702 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstFrameSize *) {
703     return Stage1ZirInstIdFrameSize;
704 }
705 
ir_inst_id(Stage1ZirInstAlignOf *)706 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAlignOf *) {
707     return Stage1ZirInstIdAlignOf;
708 }
709 
ir_inst_id(Stage1ZirInstOverflowOp *)710 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstOverflowOp *) {
711     return Stage1ZirInstIdOverflowOp;
712 }
713 
ir_inst_id(Stage1ZirInstTestErr *)714 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstTestErr *) {
715     return Stage1ZirInstIdTestErr;
716 }
717 
ir_inst_id(Stage1ZirInstMulAdd *)718 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstMulAdd *) {
719     return Stage1ZirInstIdMulAdd;
720 }
721 
ir_inst_id(Stage1ZirInstFloatOp *)722 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstFloatOp *) {
723     return Stage1ZirInstIdFloatOp;
724 }
725 
ir_inst_id(Stage1ZirInstUnwrapErrCode *)726 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstUnwrapErrCode *) {
727     return Stage1ZirInstIdUnwrapErrCode;
728 }
729 
ir_inst_id(Stage1ZirInstUnwrapErrPayload *)730 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstUnwrapErrPayload *) {
731     return Stage1ZirInstIdUnwrapErrPayload;
732 }
733 
ir_inst_id(Stage1ZirInstFnProto *)734 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstFnProto *) {
735     return Stage1ZirInstIdFnProto;
736 }
737 
ir_inst_id(Stage1ZirInstTestComptime *)738 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstTestComptime *) {
739     return Stage1ZirInstIdTestComptime;
740 }
741 
ir_inst_id(Stage1ZirInstPtrCast *)742 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPtrCast *) {
743     return Stage1ZirInstIdPtrCast;
744 }
745 
ir_inst_id(Stage1ZirInstBitCast *)746 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstBitCast *) {
747     return Stage1ZirInstIdBitCast;
748 }
749 
ir_inst_id(Stage1ZirInstIntToPtr *)750 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstIntToPtr *) {
751     return Stage1ZirInstIdIntToPtr;
752 }
753 
ir_inst_id(Stage1ZirInstPtrToInt *)754 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPtrToInt *) {
755     return Stage1ZirInstIdPtrToInt;
756 }
757 
ir_inst_id(Stage1ZirInstIntToEnum *)758 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstIntToEnum *) {
759     return Stage1ZirInstIdIntToEnum;
760 }
761 
ir_inst_id(Stage1ZirInstEnumToInt *)762 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstEnumToInt *) {
763     return Stage1ZirInstIdEnumToInt;
764 }
765 
ir_inst_id(Stage1ZirInstIntToErr *)766 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstIntToErr *) {
767     return Stage1ZirInstIdIntToErr;
768 }
769 
ir_inst_id(Stage1ZirInstErrToInt *)770 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstErrToInt *) {
771     return Stage1ZirInstIdErrToInt;
772 }
773 
ir_inst_id(Stage1ZirInstCheckStatementIsVoid *)774 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCheckStatementIsVoid *) {
775     return Stage1ZirInstIdCheckStatementIsVoid;
776 }
777 
ir_inst_id(Stage1ZirInstTypeName *)778 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstTypeName *) {
779     return Stage1ZirInstIdTypeName;
780 }
781 
ir_inst_id(Stage1ZirInstDeclRef *)782 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstDeclRef *) {
783     return Stage1ZirInstIdDeclRef;
784 }
785 
ir_inst_id(Stage1ZirInstPanic *)786 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPanic *) {
787     return Stage1ZirInstIdPanic;
788 }
789 
ir_inst_id(Stage1ZirInstTagName *)790 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstTagName *) {
791     return Stage1ZirInstIdTagName;
792 }
793 
ir_inst_id(Stage1ZirInstFieldParentPtr *)794 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstFieldParentPtr *) {
795     return Stage1ZirInstIdFieldParentPtr;
796 }
797 
ir_inst_id(Stage1ZirInstOffsetOf *)798 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstOffsetOf *) {
799     return Stage1ZirInstIdOffsetOf;
800 }
801 
ir_inst_id(Stage1ZirInstBitOffsetOf *)802 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstBitOffsetOf *) {
803     return Stage1ZirInstIdBitOffsetOf;
804 }
805 
ir_inst_id(Stage1ZirInstTypeInfo *)806 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstTypeInfo *) {
807     return Stage1ZirInstIdTypeInfo;
808 }
809 
ir_inst_id(Stage1ZirInstType *)810 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstType *) {
811     return Stage1ZirInstIdType;
812 }
813 
ir_inst_id(Stage1ZirInstHasField *)814 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstHasField *) {
815     return Stage1ZirInstIdHasField;
816 }
817 
ir_inst_id(Stage1ZirInstSetEvalBranchQuota *)818 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSetEvalBranchQuota *) {
819     return Stage1ZirInstIdSetEvalBranchQuota;
820 }
821 
ir_inst_id(Stage1ZirInstPtrType *)822 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPtrType *) {
823     return Stage1ZirInstIdPtrType;
824 }
825 
ir_inst_id(Stage1ZirInstAlignCast *)826 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAlignCast *) {
827     return Stage1ZirInstIdAlignCast;
828 }
829 
ir_inst_id(Stage1ZirInstImplicitCast *)830 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstImplicitCast *) {
831     return Stage1ZirInstIdImplicitCast;
832 }
833 
ir_inst_id(Stage1ZirInstResolveResult *)834 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstResolveResult *) {
835     return Stage1ZirInstIdResolveResult;
836 }
837 
ir_inst_id(Stage1ZirInstResetResult *)838 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstResetResult *) {
839     return Stage1ZirInstIdResetResult;
840 }
841 
ir_inst_id(Stage1ZirInstSetAlignStack *)842 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSetAlignStack *) {
843     return Stage1ZirInstIdSetAlignStack;
844 }
845 
ir_inst_id(Stage1ZirInstExport *)846 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstExport *) {
847     return Stage1ZirInstIdExport;
848 }
849 
ir_inst_id(Stage1ZirInstExtern *)850 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstExtern *) {
851     return Stage1ZirInstIdExtern;
852 }
853 
ir_inst_id(Stage1ZirInstErrorReturnTrace *)854 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstErrorReturnTrace *) {
855     return Stage1ZirInstIdErrorReturnTrace;
856 }
857 
ir_inst_id(Stage1ZirInstErrorUnion *)858 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstErrorUnion *) {
859     return Stage1ZirInstIdErrorUnion;
860 }
861 
ir_inst_id(Stage1ZirInstAtomicRmw *)862 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAtomicRmw *) {
863     return Stage1ZirInstIdAtomicRmw;
864 }
865 
ir_inst_id(Stage1ZirInstAtomicLoad *)866 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAtomicLoad *) {
867     return Stage1ZirInstIdAtomicLoad;
868 }
869 
ir_inst_id(Stage1ZirInstAtomicStore *)870 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAtomicStore *) {
871     return Stage1ZirInstIdAtomicStore;
872 }
873 
ir_inst_id(Stage1ZirInstSaveErrRetAddr *)874 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSaveErrRetAddr *) {
875     return Stage1ZirInstIdSaveErrRetAddr;
876 }
877 
ir_inst_id(Stage1ZirInstAddImplicitReturnType *)878 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAddImplicitReturnType *) {
879     return Stage1ZirInstIdAddImplicitReturnType;
880 }
881 
ir_inst_id(Stage1ZirInstErrSetCast *)882 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstErrSetCast *) {
883     return Stage1ZirInstIdErrSetCast;
884 }
885 
ir_inst_id(Stage1ZirInstCheckRuntimeScope *)886 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstCheckRuntimeScope *) {
887     return Stage1ZirInstIdCheckRuntimeScope;
888 }
889 
ir_inst_id(Stage1ZirInstHasDecl *)890 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstHasDecl *) {
891     return Stage1ZirInstIdHasDecl;
892 }
893 
ir_inst_id(Stage1ZirInstUndeclaredIdent *)894 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstUndeclaredIdent *) {
895     return Stage1ZirInstIdUndeclaredIdent;
896 }
897 
ir_inst_id(Stage1ZirInstAlloca *)898 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAlloca *) {
899     return Stage1ZirInstIdAlloca;
900 }
901 
ir_inst_id(Stage1ZirInstEndExpr *)902 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstEndExpr *) {
903     return Stage1ZirInstIdEndExpr;
904 }
905 
ir_inst_id(Stage1ZirInstUnionInitNamedField *)906 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstUnionInitNamedField *) {
907     return Stage1ZirInstIdUnionInitNamedField;
908 }
909 
ir_inst_id(Stage1ZirInstSuspendBegin *)910 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSuspendBegin *) {
911     return Stage1ZirInstIdSuspendBegin;
912 }
913 
ir_inst_id(Stage1ZirInstSuspendFinish *)914 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSuspendFinish *) {
915     return Stage1ZirInstIdSuspendFinish;
916 }
917 
ir_inst_id(Stage1ZirInstAwait *)918 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstAwait *) {
919     return Stage1ZirInstIdAwait;
920 }
921 
ir_inst_id(Stage1ZirInstResume *)922 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstResume *) {
923     return Stage1ZirInstIdResume;
924 }
925 
ir_inst_id(Stage1ZirInstSpillBegin *)926 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSpillBegin *) {
927     return Stage1ZirInstIdSpillBegin;
928 }
929 
ir_inst_id(Stage1ZirInstSpillEnd *)930 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSpillEnd *) {
931     return Stage1ZirInstIdSpillEnd;
932 }
933 
ir_inst_id(Stage1ZirInstWasmMemorySize *)934 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstWasmMemorySize *) {
935     return Stage1ZirInstIdWasmMemorySize;
936 }
937 
ir_inst_id(Stage1ZirInstWasmMemoryGrow *)938 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstWasmMemoryGrow *) {
939     return Stage1ZirInstIdWasmMemoryGrow;
940 }
941 
ir_inst_id(Stage1ZirInstSrc *)942 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstSrc *) {
943     return Stage1ZirInstIdSrc;
944 }
945 
ir_inst_id(Stage1ZirInstPrefetch *)946 static constexpr Stage1ZirInstId ir_inst_id(Stage1ZirInstPrefetch *) {
947     return Stage1ZirInstIdPrefetch;
948 }
949 
950 template<typename T>
ir_create_instruction(Stage1AstGen * ag,Scope * scope,AstNode * source_node)951 static T *ir_create_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
952     T *special_instruction = heap::c_allocator.create<T>();
953     special_instruction->base.id = ir_inst_id(special_instruction);
954     special_instruction->base.scope = scope;
955     special_instruction->base.source_node = source_node;
956     special_instruction->base.debug_id = irb_next_debug_id(ag);
957     special_instruction->base.owner_bb = ag->current_basic_block;
958     return special_instruction;
959 }
960 
961 template<typename T>
ir_build_instruction(Stage1AstGen * ag,Scope * scope,AstNode * source_node)962 static T *ir_build_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
963     T *special_instruction = ir_create_instruction<T>(ag, scope, source_node);
964     ir_instruction_append(ag->current_basic_block, &special_instruction->base);
965     return special_instruction;
966 }
967 
ir_build_cond_br(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * condition,Stage1ZirBasicBlock * then_block,Stage1ZirBasicBlock * else_block,Stage1ZirInst * is_comptime)968 static Stage1ZirInst *ir_build_cond_br(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *condition,
969         Stage1ZirBasicBlock *then_block, Stage1ZirBasicBlock *else_block, Stage1ZirInst *is_comptime)
970 {
971     Stage1ZirInstCondBr *inst = ir_build_instruction<Stage1ZirInstCondBr>(ag, scope, source_node);
972     inst->condition = condition;
973     inst->then_block = then_block;
974     inst->else_block = else_block;
975     inst->is_comptime = is_comptime;
976 
977     ir_ref_instruction(condition, ag->current_basic_block);
978     ir_ref_bb(then_block);
979     ir_ref_bb(else_block);
980     if (is_comptime != nullptr) ir_ref_instruction(is_comptime, ag->current_basic_block);
981 
982     return &inst->base;
983 }
984 
ir_build_return_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * operand)985 static Stage1ZirInst *ir_build_return_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *operand) {
986     Stage1ZirInstReturn *inst = ir_build_instruction<Stage1ZirInstReturn>(ag, scope, source_node);
987     inst->operand = operand;
988 
989     if (operand != nullptr) ir_ref_instruction(operand, ag->current_basic_block);
990 
991     return &inst->base;
992 }
993 
ir_build_const_void(Stage1AstGen * ag,Scope * scope,AstNode * source_node)994 static Stage1ZirInst *ir_build_const_void(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
995     Stage1ZirInstConst *const_instruction = ir_create_instruction<Stage1ZirInstConst>(ag, scope, source_node);
996     ir_instruction_append(ag->current_basic_block, &const_instruction->base);
997     const_instruction->value = ag->codegen->intern.for_void();
998     return &const_instruction->base;
999 }
1000 
ir_build_const_undefined(Stage1AstGen * ag,Scope * scope,AstNode * source_node)1001 static Stage1ZirInst *ir_build_const_undefined(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
1002     Stage1ZirInstConst *const_instruction = ir_create_instruction<Stage1ZirInstConst>(ag, scope, source_node);
1003     ir_instruction_append(ag->current_basic_block, &const_instruction->base);
1004     const_instruction->value = ag->codegen->intern.for_undefined();
1005     const_instruction->value->special = ConstValSpecialUndef;
1006     return &const_instruction->base;
1007 }
1008 
ir_build_const_uint(Stage1AstGen * ag,Scope * scope,AstNode * source_node,uint64_t value)1009 static Stage1ZirInst *ir_build_const_uint(Stage1AstGen *ag, Scope *scope, AstNode *source_node, uint64_t value) {
1010     Stage1ZirInstConst *const_instruction = ir_build_instruction<Stage1ZirInstConst>(ag, scope, source_node);
1011     const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1012     const_instruction->value->type = ag->codegen->builtin_types.entry_num_lit_int;
1013     const_instruction->value->special = ConstValSpecialStatic;
1014     bigint_init_unsigned(&const_instruction->value->data.x_bigint, value);
1015     return &const_instruction->base;
1016 }
1017 
ir_build_const_bigint(Stage1AstGen * ag,Scope * scope,AstNode * source_node,BigInt bigint)1018 static Stage1ZirInst *ir_build_const_bigint(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1019         BigInt bigint)
1020 {
1021     Stage1ZirInstConst *const_instruction = ir_build_instruction<Stage1ZirInstConst>(ag, scope, source_node);
1022     const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1023     const_instruction->value->type = ag->codegen->builtin_types.entry_num_lit_int;
1024     const_instruction->value->special = ConstValSpecialStatic;
1025     const_instruction->value->data.x_bigint = bigint;
1026     return &const_instruction->base;
1027 }
1028 
ir_build_const_bigfloat(Stage1AstGen * ag,Scope * scope,AstNode * source_node,BigFloat bigfloat)1029 static Stage1ZirInst *ir_build_const_bigfloat(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1030         BigFloat bigfloat)
1031 {
1032     Stage1ZirInstConst *const_instruction = ir_build_instruction<Stage1ZirInstConst>(ag, scope, source_node);
1033     const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1034     const_instruction->value->type = ag->codegen->builtin_types.entry_num_lit_float;
1035     const_instruction->value->special = ConstValSpecialStatic;
1036     const_instruction->value->data.x_bigfloat = bigfloat;
1037     return &const_instruction->base;
1038 }
1039 
ir_build_const_null(Stage1AstGen * ag,Scope * scope,AstNode * source_node)1040 static Stage1ZirInst *ir_build_const_null(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
1041     Stage1ZirInstConst *const_instruction = ir_create_instruction<Stage1ZirInstConst>(ag, scope, source_node);
1042     ir_instruction_append(ag->current_basic_block, &const_instruction->base);
1043     const_instruction->value = ag->codegen->intern.for_null();
1044     return &const_instruction->base;
1045 }
1046 
ir_build_const_usize(Stage1AstGen * ag,Scope * scope,AstNode * source_node,uint64_t value)1047 static Stage1ZirInst *ir_build_const_usize(Stage1AstGen *ag, Scope *scope, AstNode *source_node, uint64_t value) {
1048     Stage1ZirInstConst *const_instruction = ir_build_instruction<Stage1ZirInstConst>(ag, scope, source_node);
1049     const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1050     const_instruction->value->type = ag->codegen->builtin_types.entry_usize;
1051     const_instruction->value->special = ConstValSpecialStatic;
1052     bigint_init_unsigned(&const_instruction->value->data.x_bigint, value);
1053     return &const_instruction->base;
1054 }
1055 
ir_create_const_type(Stage1AstGen * ag,Scope * scope,AstNode * source_node,ZigType * type_entry)1056 static Stage1ZirInst *ir_create_const_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1057         ZigType *type_entry)
1058 {
1059     Stage1ZirInstConst *const_instruction = ir_create_instruction<Stage1ZirInstConst>(ag, scope, source_node);
1060     const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1061     const_instruction->value->type = ag->codegen->builtin_types.entry_type;
1062     const_instruction->value->special = ConstValSpecialStatic;
1063     const_instruction->value->data.x_type = type_entry;
1064     return &const_instruction->base;
1065 }
1066 
ir_build_const_type(Stage1AstGen * ag,Scope * scope,AstNode * source_node,ZigType * type_entry)1067 static Stage1ZirInst *ir_build_const_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1068         ZigType *type_entry)
1069 {
1070     Stage1ZirInst *instruction = ir_create_const_type(ag, scope, source_node, type_entry);
1071     ir_instruction_append(ag->current_basic_block, instruction);
1072     return instruction;
1073 }
1074 
ir_build_const_import(Stage1AstGen * ag,Scope * scope,AstNode * source_node,ZigType * import)1075 static Stage1ZirInst *ir_build_const_import(Stage1AstGen *ag, Scope *scope, AstNode *source_node, ZigType *import) {
1076     Stage1ZirInstConst *const_instruction = ir_build_instruction<Stage1ZirInstConst>(ag, scope, source_node);
1077     const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1078     const_instruction->value->type = ag->codegen->builtin_types.entry_type;
1079     const_instruction->value->special = ConstValSpecialStatic;
1080     const_instruction->value->data.x_type = import;
1081     return &const_instruction->base;
1082 }
1083 
ir_build_const_bool(Stage1AstGen * ag,Scope * scope,AstNode * source_node,bool value)1084 static Stage1ZirInst *ir_build_const_bool(Stage1AstGen *ag, Scope *scope, AstNode *source_node, bool value) {
1085     Stage1ZirInstConst *const_instruction = ir_build_instruction<Stage1ZirInstConst>(ag, scope, source_node);
1086     const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1087     const_instruction->value->type = ag->codegen->builtin_types.entry_bool;
1088     const_instruction->value->special = ConstValSpecialStatic;
1089     const_instruction->value->data.x_bool = value;
1090     return &const_instruction->base;
1091 }
1092 
ir_build_const_enum_literal(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Buf * name)1093 static Stage1ZirInst *ir_build_const_enum_literal(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Buf *name) {
1094     Stage1ZirInstConst *const_instruction = ir_build_instruction<Stage1ZirInstConst>(ag, scope, source_node);
1095     const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1096     const_instruction->value->type = ag->codegen->builtin_types.entry_enum_literal;
1097     const_instruction->value->special = ConstValSpecialStatic;
1098     const_instruction->value->data.x_enum_literal = name;
1099     return &const_instruction->base;
1100 }
1101 
1102 // Consumes `str`.
ir_create_const_str_lit(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Buf * str)1103 static Stage1ZirInst *ir_create_const_str_lit(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Buf *str) {
1104     Stage1ZirInstConst *const_instruction = ir_create_instruction<Stage1ZirInstConst>(ag, scope, source_node);
1105     const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
1106     init_const_str_lit(ag->codegen, const_instruction->value, str, true);
1107 
1108     return &const_instruction->base;
1109 }
1110 
1111 // Consumes `str`.
ir_build_const_str_lit(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Buf * str)1112 static Stage1ZirInst *ir_build_const_str_lit(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Buf *str) {
1113     Stage1ZirInst *instruction = ir_create_const_str_lit(ag, scope, source_node, str);
1114     ir_instruction_append(ag->current_basic_block, instruction);
1115     return instruction;
1116 }
1117 
ir_build_bin_op(Stage1AstGen * ag,Scope * scope,AstNode * source_node,IrBinOp op_id,Stage1ZirInst * op1,Stage1ZirInst * op2,bool safety_check_on)1118 static Stage1ZirInst *ir_build_bin_op(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrBinOp op_id,
1119         Stage1ZirInst *op1, Stage1ZirInst *op2, bool safety_check_on)
1120 {
1121     Stage1ZirInstBinOp *inst = ir_build_instruction<Stage1ZirInstBinOp>(ag, scope, source_node);
1122     inst->op_id = op_id;
1123     inst->op1 = op1;
1124     inst->op2 = op2;
1125     inst->safety_check_on = safety_check_on;
1126 
1127     ir_ref_instruction(op1, ag->current_basic_block);
1128     ir_ref_instruction(op2, ag->current_basic_block);
1129 
1130     return &inst->base;
1131 }
1132 
ir_build_merge_err_sets(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * op1,Stage1ZirInst * op2,Buf * type_name)1133 static Stage1ZirInst *ir_build_merge_err_sets(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1134         Stage1ZirInst *op1, Stage1ZirInst *op2, Buf *type_name)
1135 {
1136     Stage1ZirInstMergeErrSets *inst = ir_build_instruction<Stage1ZirInstMergeErrSets>(ag, scope, source_node);
1137     inst->op1 = op1;
1138     inst->op2 = op2;
1139     inst->type_name = type_name;
1140 
1141     ir_ref_instruction(op1, ag->current_basic_block);
1142     ir_ref_instruction(op2, ag->current_basic_block);
1143 
1144     return &inst->base;
1145 }
1146 
ir_build_var_ptr_x(Stage1AstGen * ag,Scope * scope,AstNode * source_node,ZigVar * var,ScopeFnDef * crossed_fndef_scope)1147 static Stage1ZirInst *ir_build_var_ptr_x(Stage1AstGen *ag, Scope *scope, AstNode *source_node, ZigVar *var,
1148         ScopeFnDef *crossed_fndef_scope)
1149 {
1150     Stage1ZirInstVarPtr *instruction = ir_build_instruction<Stage1ZirInstVarPtr>(ag, scope, source_node);
1151     instruction->var = var;
1152     instruction->crossed_fndef_scope = crossed_fndef_scope;
1153 
1154     var->ref_count += 1;
1155 
1156     return &instruction->base;
1157 }
1158 
ir_build_var_ptr(Stage1AstGen * ag,Scope * scope,AstNode * source_node,ZigVar * var)1159 static Stage1ZirInst *ir_build_var_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node, ZigVar *var) {
1160     return ir_build_var_ptr_x(ag, scope, source_node, var, nullptr);
1161 }
1162 
ir_build_elem_ptr(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * array_ptr,Stage1ZirInst * elem_index,bool safety_check_on,PtrLen ptr_len,AstNode * init_array_type_source_node)1163 static Stage1ZirInst *ir_build_elem_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1164         Stage1ZirInst *array_ptr, Stage1ZirInst *elem_index, bool safety_check_on, PtrLen ptr_len,
1165         AstNode *init_array_type_source_node)
1166 {
1167     Stage1ZirInstElemPtr *instruction = ir_build_instruction<Stage1ZirInstElemPtr>(ag, scope, source_node);
1168     instruction->array_ptr = array_ptr;
1169     instruction->elem_index = elem_index;
1170     instruction->safety_check_on = safety_check_on;
1171     instruction->ptr_len = ptr_len;
1172     instruction->init_array_type_source_node = init_array_type_source_node;
1173 
1174     ir_ref_instruction(array_ptr, ag->current_basic_block);
1175     ir_ref_instruction(elem_index, ag->current_basic_block);
1176 
1177     return &instruction->base;
1178 }
1179 
ir_build_field_ptr_instruction(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * container_ptr,Stage1ZirInst * field_name_expr,bool initializing)1180 static Stage1ZirInst *ir_build_field_ptr_instruction(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1181     Stage1ZirInst *container_ptr, Stage1ZirInst *field_name_expr, bool initializing)
1182 {
1183     Stage1ZirInstFieldPtr *instruction = ir_build_instruction<Stage1ZirInstFieldPtr>(ag, scope, source_node);
1184     instruction->container_ptr = container_ptr;
1185     instruction->field_name_buffer = nullptr;
1186     instruction->field_name_expr = field_name_expr;
1187     instruction->initializing = initializing;
1188 
1189     ir_ref_instruction(container_ptr, ag->current_basic_block);
1190     ir_ref_instruction(field_name_expr, ag->current_basic_block);
1191 
1192     return &instruction->base;
1193 }
1194 
ir_build_field_ptr(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * container_ptr,Buf * field_name,bool initializing)1195 static Stage1ZirInst *ir_build_field_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1196     Stage1ZirInst *container_ptr, Buf *field_name, bool initializing)
1197 {
1198     Stage1ZirInstFieldPtr *instruction = ir_build_instruction<Stage1ZirInstFieldPtr>(ag, scope, source_node);
1199     instruction->container_ptr = container_ptr;
1200     instruction->field_name_buffer = field_name;
1201     instruction->field_name_expr = nullptr;
1202     instruction->initializing = initializing;
1203 
1204     ir_ref_instruction(container_ptr, ag->current_basic_block);
1205 
1206     return &instruction->base;
1207 }
1208 
ir_build_has_field(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * container_type,Stage1ZirInst * field_name)1209 static Stage1ZirInst *ir_build_has_field(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1210     Stage1ZirInst *container_type, Stage1ZirInst *field_name)
1211 {
1212     Stage1ZirInstHasField *instruction = ir_build_instruction<Stage1ZirInstHasField>(ag, scope, source_node);
1213     instruction->container_type = container_type;
1214     instruction->field_name = field_name;
1215 
1216     ir_ref_instruction(container_type, ag->current_basic_block);
1217     ir_ref_instruction(field_name, ag->current_basic_block);
1218 
1219     return &instruction->base;
1220 }
1221 
ir_build_call_extra(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * options,Stage1ZirInst * fn_ref,Stage1ZirInst * args,ResultLoc * result_loc)1222 static Stage1ZirInst *ir_build_call_extra(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1223         Stage1ZirInst *options, Stage1ZirInst *fn_ref, Stage1ZirInst *args, ResultLoc *result_loc)
1224 {
1225     Stage1ZirInstCallExtra *call_instruction = ir_build_instruction<Stage1ZirInstCallExtra>(ag, scope, source_node);
1226     call_instruction->options = options;
1227     call_instruction->fn_ref = fn_ref;
1228     call_instruction->args = args;
1229     call_instruction->result_loc = result_loc;
1230 
1231     ir_ref_instruction(options, ag->current_basic_block);
1232     ir_ref_instruction(fn_ref, ag->current_basic_block);
1233     ir_ref_instruction(args, ag->current_basic_block);
1234 
1235     return &call_instruction->base;
1236 }
1237 
ir_build_async_call_extra(Stage1AstGen * ag,Scope * scope,AstNode * source_node,CallModifier modifier,Stage1ZirInst * fn_ref,Stage1ZirInst * ret_ptr,Stage1ZirInst * new_stack,Stage1ZirInst * args,ResultLoc * result_loc)1238 static Stage1ZirInst *ir_build_async_call_extra(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1239         CallModifier modifier, Stage1ZirInst *fn_ref, Stage1ZirInst *ret_ptr, Stage1ZirInst *new_stack, Stage1ZirInst *args, ResultLoc *result_loc)
1240 {
1241     Stage1ZirInstAsyncCallExtra *call_instruction = ir_build_instruction<Stage1ZirInstAsyncCallExtra>(ag, scope, source_node);
1242     call_instruction->modifier = modifier;
1243     call_instruction->fn_ref = fn_ref;
1244     call_instruction->ret_ptr = ret_ptr;
1245     call_instruction->new_stack = new_stack;
1246     call_instruction->args = args;
1247     call_instruction->result_loc = result_loc;
1248 
1249     ir_ref_instruction(fn_ref, ag->current_basic_block);
1250     if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, ag->current_basic_block);
1251     ir_ref_instruction(new_stack, ag->current_basic_block);
1252     ir_ref_instruction(args, ag->current_basic_block);
1253 
1254     return &call_instruction->base;
1255 }
1256 
ir_build_call_args(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * options,Stage1ZirInst * fn_ref,Stage1ZirInst ** args_ptr,size_t args_len,ResultLoc * result_loc)1257 static Stage1ZirInst *ir_build_call_args(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1258         Stage1ZirInst *options, Stage1ZirInst *fn_ref, Stage1ZirInst **args_ptr, size_t args_len,
1259         ResultLoc *result_loc)
1260 {
1261     Stage1ZirInstCallArgs *call_instruction = ir_build_instruction<Stage1ZirInstCallArgs>(ag, scope, source_node);
1262     call_instruction->options = options;
1263     call_instruction->fn_ref = fn_ref;
1264     call_instruction->args_ptr = args_ptr;
1265     call_instruction->args_len = args_len;
1266     call_instruction->result_loc = result_loc;
1267 
1268     ir_ref_instruction(options, ag->current_basic_block);
1269     ir_ref_instruction(fn_ref, ag->current_basic_block);
1270     for (size_t i = 0; i < args_len; i += 1)
1271         ir_ref_instruction(args_ptr[i], ag->current_basic_block);
1272 
1273     return &call_instruction->base;
1274 }
1275 
ir_build_call_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,ZigFn * fn_entry,Stage1ZirInst * fn_ref,size_t arg_count,Stage1ZirInst ** args,Stage1ZirInst * ret_ptr,CallModifier modifier,bool is_async_call_builtin,Stage1ZirInst * new_stack,ResultLoc * result_loc)1276 static Stage1ZirInst *ir_build_call_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1277         ZigFn *fn_entry, Stage1ZirInst *fn_ref, size_t arg_count, Stage1ZirInst **args,
1278         Stage1ZirInst *ret_ptr, CallModifier modifier, bool is_async_call_builtin,
1279         Stage1ZirInst *new_stack, ResultLoc *result_loc)
1280 {
1281     Stage1ZirInstCall *call_instruction = ir_build_instruction<Stage1ZirInstCall>(ag, scope, source_node);
1282     call_instruction->fn_entry = fn_entry;
1283     call_instruction->fn_ref = fn_ref;
1284     call_instruction->args = args;
1285     call_instruction->arg_count = arg_count;
1286     call_instruction->modifier = modifier;
1287     call_instruction->is_async_call_builtin = is_async_call_builtin;
1288     call_instruction->new_stack = new_stack;
1289     call_instruction->result_loc = result_loc;
1290     call_instruction->ret_ptr = ret_ptr;
1291 
1292     if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ag->current_basic_block);
1293     for (size_t i = 0; i < arg_count; i += 1)
1294         ir_ref_instruction(args[i], ag->current_basic_block);
1295     if (ret_ptr != nullptr) ir_ref_instruction(ret_ptr, ag->current_basic_block);
1296     if (new_stack != nullptr) ir_ref_instruction(new_stack, ag->current_basic_block);
1297 
1298     return &call_instruction->base;
1299 }
1300 
ir_build_phi(Stage1AstGen * ag,Scope * scope,AstNode * source_node,size_t incoming_count,Stage1ZirBasicBlock ** incoming_blocks,Stage1ZirInst ** incoming_values,ResultLocPeerParent * peer_parent)1301 static Stage1ZirInst *ir_build_phi(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1302         size_t incoming_count, Stage1ZirBasicBlock **incoming_blocks, Stage1ZirInst **incoming_values,
1303         ResultLocPeerParent *peer_parent)
1304 {
1305     assert(incoming_count != 0);
1306     assert(incoming_count != SIZE_MAX);
1307 
1308     Stage1ZirInstPhi *phi_instruction = ir_build_instruction<Stage1ZirInstPhi>(ag, scope, source_node);
1309     phi_instruction->incoming_count = incoming_count;
1310     phi_instruction->incoming_blocks = incoming_blocks;
1311     phi_instruction->incoming_values = incoming_values;
1312     phi_instruction->peer_parent = peer_parent;
1313 
1314     for (size_t i = 0; i < incoming_count; i += 1) {
1315         ir_ref_bb(incoming_blocks[i]);
1316         ir_ref_instruction(incoming_values[i], ag->current_basic_block);
1317     }
1318 
1319     return &phi_instruction->base;
1320 }
1321 
ir_build_br(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirBasicBlock * dest_block,Stage1ZirInst * is_comptime)1322 static Stage1ZirInst *ir_build_br(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1323         Stage1ZirBasicBlock *dest_block, Stage1ZirInst *is_comptime)
1324 {
1325     Stage1ZirInstBr *inst = ir_build_instruction<Stage1ZirInstBr>(ag, scope, source_node);
1326     inst->dest_block = dest_block;
1327     inst->is_comptime = is_comptime;
1328 
1329     ir_ref_bb(dest_block);
1330     if (is_comptime) ir_ref_instruction(is_comptime, ag->current_basic_block);
1331 
1332     return &inst->base;
1333 }
1334 
ir_build_ptr_type_simple(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * child_type,bool is_const)1335 static Stage1ZirInst *ir_build_ptr_type_simple(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1336         Stage1ZirInst *child_type, bool is_const)
1337 {
1338     Stage1ZirInstPtrTypeSimple *inst = heap::c_allocator.create<Stage1ZirInstPtrTypeSimple>();
1339     inst->base.id = is_const ? Stage1ZirInstIdPtrTypeSimpleConst : Stage1ZirInstIdPtrTypeSimple;
1340     inst->base.scope = scope;
1341     inst->base.source_node = source_node;
1342     inst->base.debug_id = irb_next_debug_id(ag);
1343     inst->base.owner_bb = ag->current_basic_block;
1344     ir_instruction_append(ag->current_basic_block, &inst->base);
1345 
1346     inst->child_type = child_type;
1347 
1348     ir_ref_instruction(child_type, ag->current_basic_block);
1349 
1350     return &inst->base;
1351 }
1352 
ir_build_ptr_type(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * child_type,bool is_const,bool is_volatile,PtrLen ptr_len,Stage1ZirInst * sentinel,Stage1ZirInst * align_value,uint32_t bit_offset_start,uint32_t host_int_bytes,bool is_allow_zero)1353 static Stage1ZirInst *ir_build_ptr_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1354         Stage1ZirInst *child_type, bool is_const, bool is_volatile, PtrLen ptr_len,
1355         Stage1ZirInst *sentinel, Stage1ZirInst *align_value,
1356         uint32_t bit_offset_start, uint32_t host_int_bytes, bool is_allow_zero)
1357 {
1358     if (!is_volatile && ptr_len == PtrLenSingle && sentinel == nullptr && align_value == nullptr &&
1359             bit_offset_start == 0 && host_int_bytes == 0 && is_allow_zero == 0)
1360     {
1361         return ir_build_ptr_type_simple(ag, scope, source_node, child_type, is_const);
1362     }
1363 
1364     Stage1ZirInstPtrType *inst = ir_build_instruction<Stage1ZirInstPtrType>(ag, scope, source_node);
1365     inst->sentinel = sentinel;
1366     inst->align_value = align_value;
1367     inst->child_type = child_type;
1368     inst->is_const = is_const;
1369     inst->is_volatile = is_volatile;
1370     inst->ptr_len = ptr_len;
1371     inst->bit_offset_start = bit_offset_start;
1372     inst->host_int_bytes = host_int_bytes;
1373     inst->is_allow_zero = is_allow_zero;
1374 
1375     if (sentinel) ir_ref_instruction(sentinel, ag->current_basic_block);
1376     if (align_value) ir_ref_instruction(align_value, ag->current_basic_block);
1377     ir_ref_instruction(child_type, ag->current_basic_block);
1378 
1379     return &inst->base;
1380 }
1381 
ir_build_un_op_lval(Stage1AstGen * ag,Scope * scope,AstNode * source_node,IrUnOp op_id,Stage1ZirInst * value,LVal lval,ResultLoc * result_loc)1382 static Stage1ZirInst *ir_build_un_op_lval(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrUnOp op_id,
1383         Stage1ZirInst *value, LVal lval, ResultLoc *result_loc)
1384 {
1385     Stage1ZirInstUnOp *instruction = ir_build_instruction<Stage1ZirInstUnOp>(ag, scope, source_node);
1386     instruction->op_id = op_id;
1387     instruction->value = value;
1388     instruction->lval = lval;
1389     instruction->result_loc = result_loc;
1390 
1391     ir_ref_instruction(value, ag->current_basic_block);
1392 
1393     return &instruction->base;
1394 }
1395 
ir_build_un_op(Stage1AstGen * ag,Scope * scope,AstNode * source_node,IrUnOp op_id,Stage1ZirInst * value)1396 static Stage1ZirInst *ir_build_un_op(Stage1AstGen *ag, Scope *scope, AstNode *source_node, IrUnOp op_id,
1397         Stage1ZirInst *value)
1398 {
1399     return ir_build_un_op_lval(ag, scope, source_node, op_id, value, LValNone, nullptr);
1400 }
1401 
ir_build_container_init_list(Stage1AstGen * ag,Scope * scope,AstNode * source_node,size_t item_count,Stage1ZirInst ** elem_result_loc_list,Stage1ZirInst * result_loc,AstNode * init_array_type_source_node)1402 static Stage1ZirInst *ir_build_container_init_list(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1403         size_t item_count, Stage1ZirInst **elem_result_loc_list, Stage1ZirInst *result_loc,
1404         AstNode *init_array_type_source_node)
1405 {
1406     Stage1ZirInstContainerInitList *container_init_list_instruction =
1407         ir_build_instruction<Stage1ZirInstContainerInitList>(ag, scope, source_node);
1408     container_init_list_instruction->item_count = item_count;
1409     container_init_list_instruction->elem_result_loc_list = elem_result_loc_list;
1410     container_init_list_instruction->result_loc = result_loc;
1411     container_init_list_instruction->init_array_type_source_node = init_array_type_source_node;
1412 
1413     for (size_t i = 0; i < item_count; i += 1) {
1414         ir_ref_instruction(elem_result_loc_list[i], ag->current_basic_block);
1415     }
1416     if (result_loc != nullptr) ir_ref_instruction(result_loc, ag->current_basic_block);
1417 
1418     return &container_init_list_instruction->base;
1419 }
1420 
ir_build_container_init_fields(Stage1AstGen * ag,Scope * scope,AstNode * source_node,size_t field_count,Stage1ZirInstContainerInitFieldsField * fields,Stage1ZirInst * result_loc)1421 static Stage1ZirInst *ir_build_container_init_fields(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1422         size_t field_count, Stage1ZirInstContainerInitFieldsField *fields, Stage1ZirInst *result_loc)
1423 {
1424     Stage1ZirInstContainerInitFields *container_init_fields_instruction =
1425         ir_build_instruction<Stage1ZirInstContainerInitFields>(ag, scope, source_node);
1426     container_init_fields_instruction->field_count = field_count;
1427     container_init_fields_instruction->fields = fields;
1428     container_init_fields_instruction->result_loc = result_loc;
1429 
1430     for (size_t i = 0; i < field_count; i += 1) {
1431         ir_ref_instruction(fields[i].result_loc, ag->current_basic_block);
1432     }
1433     if (result_loc != nullptr) ir_ref_instruction(result_loc, ag->current_basic_block);
1434 
1435     return &container_init_fields_instruction->base;
1436 }
1437 
ir_build_unreachable(Stage1AstGen * ag,Scope * scope,AstNode * source_node)1438 static Stage1ZirInst *ir_build_unreachable(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
1439     Stage1ZirInstUnreachable *inst = ir_build_instruction<Stage1ZirInstUnreachable>(ag, scope, source_node);
1440     return &inst->base;
1441 }
1442 
ir_build_store_ptr(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * ptr,Stage1ZirInst * value)1443 static Stage1ZirInstStorePtr *ir_build_store_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1444         Stage1ZirInst *ptr, Stage1ZirInst *value)
1445 {
1446     Stage1ZirInstStorePtr *instruction = ir_build_instruction<Stage1ZirInstStorePtr>(ag, scope, source_node);
1447     instruction->ptr = ptr;
1448     instruction->value = value;
1449 
1450     ir_ref_instruction(ptr, ag->current_basic_block);
1451     ir_ref_instruction(value, ag->current_basic_block);
1452 
1453     return instruction;
1454 }
1455 
ir_build_var_decl_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,ZigVar * var,Stage1ZirInst * align_value,Stage1ZirInst * ptr)1456 static Stage1ZirInst *ir_build_var_decl_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1457         ZigVar *var, Stage1ZirInst *align_value, Stage1ZirInst *ptr)
1458 {
1459     Stage1ZirInstDeclVar *inst = ir_build_instruction<Stage1ZirInstDeclVar>(ag, scope, source_node);
1460     inst->var = var;
1461     inst->align_value = align_value;
1462     inst->ptr = ptr;
1463 
1464     if (align_value != nullptr) ir_ref_instruction(align_value, ag->current_basic_block);
1465     ir_ref_instruction(ptr, ag->current_basic_block);
1466 
1467     return &inst->base;
1468 }
1469 
ir_build_export(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target,Stage1ZirInst * options)1470 static Stage1ZirInst *ir_build_export(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1471         Stage1ZirInst *target, Stage1ZirInst *options)
1472 {
1473     Stage1ZirInstExport *export_instruction = ir_build_instruction<Stage1ZirInstExport>(
1474             ag, scope, source_node);
1475     export_instruction->target = target;
1476     export_instruction->options = options;
1477 
1478     ir_ref_instruction(target, ag->current_basic_block);
1479     ir_ref_instruction(options, ag->current_basic_block);
1480 
1481     return &export_instruction->base;
1482 }
1483 
ir_build_extern(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type,Stage1ZirInst * options)1484 static Stage1ZirInst *ir_build_extern(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1485         Stage1ZirInst *type, Stage1ZirInst *options)
1486 {
1487     Stage1ZirInstExtern *extern_instruction = ir_build_instruction<Stage1ZirInstExtern>(
1488             ag, scope, source_node);
1489     extern_instruction->type = type;
1490     extern_instruction->options = options;
1491 
1492     ir_ref_instruction(type, ag->current_basic_block);
1493     ir_ref_instruction(options, ag->current_basic_block);
1494 
1495     return &extern_instruction->base;
1496 }
1497 
ir_build_load_ptr(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * ptr)1498 static Stage1ZirInst *ir_build_load_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *ptr) {
1499     Stage1ZirInstLoadPtr *instruction = ir_build_instruction<Stage1ZirInstLoadPtr>(ag, scope, source_node);
1500     instruction->ptr = ptr;
1501 
1502     ir_ref_instruction(ptr, ag->current_basic_block);
1503 
1504     return &instruction->base;
1505 }
1506 
ir_build_typeof_n(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst ** values,size_t value_count)1507 static Stage1ZirInst *ir_build_typeof_n(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1508         Stage1ZirInst **values, size_t value_count)
1509 {
1510     assert(value_count >= 2);
1511 
1512     Stage1ZirInstTypeOf *instruction = ir_build_instruction<Stage1ZirInstTypeOf>(ag, scope, source_node);
1513     instruction->value.list = values;
1514     instruction->value_count = value_count;
1515 
1516     for (size_t i = 0; i < value_count; i++)
1517         ir_ref_instruction(values[i], ag->current_basic_block);
1518 
1519     return &instruction->base;
1520 }
1521 
ir_build_typeof_1(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * value)1522 static Stage1ZirInst *ir_build_typeof_1(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *value) {
1523     Stage1ZirInstTypeOf *instruction = ir_build_instruction<Stage1ZirInstTypeOf>(ag, scope, source_node);
1524     instruction->value.scalar = value;
1525 
1526     ir_ref_instruction(value, ag->current_basic_block);
1527 
1528     return &instruction->base;
1529 }
1530 
ir_build_set_cold(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * is_cold)1531 static Stage1ZirInst *ir_build_set_cold(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *is_cold) {
1532     Stage1ZirInstSetCold *instruction = ir_build_instruction<Stage1ZirInstSetCold>(ag, scope, source_node);
1533     instruction->is_cold = is_cold;
1534 
1535     ir_ref_instruction(is_cold, ag->current_basic_block);
1536 
1537     return &instruction->base;
1538 }
1539 
ir_build_set_runtime_safety(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * safety_on)1540 static Stage1ZirInst *ir_build_set_runtime_safety(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1541         Stage1ZirInst *safety_on)
1542 {
1543     Stage1ZirInstSetRuntimeSafety *inst = ir_build_instruction<Stage1ZirInstSetRuntimeSafety>(ag, scope, source_node);
1544     inst->safety_on = safety_on;
1545 
1546     ir_ref_instruction(safety_on, ag->current_basic_block);
1547 
1548     return &inst->base;
1549 }
1550 
ir_build_set_float_mode(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * mode_value)1551 static Stage1ZirInst *ir_build_set_float_mode(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1552         Stage1ZirInst *mode_value)
1553 {
1554     Stage1ZirInstSetFloatMode *instruction = ir_build_instruction<Stage1ZirInstSetFloatMode>(ag, scope, source_node);
1555     instruction->mode_value = mode_value;
1556 
1557     ir_ref_instruction(mode_value, ag->current_basic_block);
1558 
1559     return &instruction->base;
1560 }
1561 
ir_build_array_type(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * size,Stage1ZirInst * sentinel,Stage1ZirInst * child_type)1562 static Stage1ZirInst *ir_build_array_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *size,
1563         Stage1ZirInst *sentinel, Stage1ZirInst *child_type)
1564 {
1565     Stage1ZirInstArrayType *instruction = ir_build_instruction<Stage1ZirInstArrayType>(ag, scope, source_node);
1566     instruction->size = size;
1567     instruction->sentinel = sentinel;
1568     instruction->child_type = child_type;
1569 
1570     ir_ref_instruction(size, ag->current_basic_block);
1571     if (sentinel != nullptr) ir_ref_instruction(sentinel, ag->current_basic_block);
1572     ir_ref_instruction(child_type, ag->current_basic_block);
1573 
1574     return &instruction->base;
1575 }
1576 
ir_build_anyframe_type(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * payload_type)1577 static Stage1ZirInst *ir_build_anyframe_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1578         Stage1ZirInst *payload_type)
1579 {
1580     Stage1ZirInstAnyFrameType *instruction = ir_build_instruction<Stage1ZirInstAnyFrameType>(ag, scope, source_node);
1581     instruction->payload_type = payload_type;
1582 
1583     if (payload_type != nullptr) ir_ref_instruction(payload_type, ag->current_basic_block);
1584 
1585     return &instruction->base;
1586 }
1587 
ir_build_slice_type(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * child_type,bool is_const,bool is_volatile,Stage1ZirInst * sentinel,Stage1ZirInst * align_value,bool is_allow_zero)1588 static Stage1ZirInst *ir_build_slice_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1589         Stage1ZirInst *child_type, bool is_const, bool is_volatile,
1590         Stage1ZirInst *sentinel, Stage1ZirInst *align_value, bool is_allow_zero)
1591 {
1592     Stage1ZirInstSliceType *instruction = ir_build_instruction<Stage1ZirInstSliceType>(ag, scope, source_node);
1593     instruction->is_const = is_const;
1594     instruction->is_volatile = is_volatile;
1595     instruction->child_type = child_type;
1596     instruction->sentinel = sentinel;
1597     instruction->align_value = align_value;
1598     instruction->is_allow_zero = is_allow_zero;
1599 
1600     if (sentinel != nullptr) ir_ref_instruction(sentinel, ag->current_basic_block);
1601     if (align_value != nullptr) ir_ref_instruction(align_value, ag->current_basic_block);
1602     ir_ref_instruction(child_type, ag->current_basic_block);
1603 
1604     return &instruction->base;
1605 }
1606 
ir_build_asm_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * asm_template,Stage1ZirInst ** input_list,Stage1ZirInst ** output_types,ZigVar ** output_vars,size_t return_count,bool has_side_effects,bool is_global)1607 static Stage1ZirInst *ir_build_asm_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1608         Stage1ZirInst *asm_template, Stage1ZirInst **input_list, Stage1ZirInst **output_types,
1609         ZigVar **output_vars, size_t return_count, bool has_side_effects, bool is_global)
1610 {
1611     Stage1ZirInstAsm *instruction = ir_build_instruction<Stage1ZirInstAsm>(ag, scope, source_node);
1612     instruction->asm_template = asm_template;
1613     instruction->input_list = input_list;
1614     instruction->output_types = output_types;
1615     instruction->output_vars = output_vars;
1616     instruction->return_count = return_count;
1617     instruction->has_side_effects = has_side_effects;
1618     instruction->is_global = is_global;
1619 
1620     assert(source_node->type == NodeTypeAsmExpr);
1621     for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) {
1622         Stage1ZirInst *output_type = output_types[i];
1623         if (output_type) ir_ref_instruction(output_type, ag->current_basic_block);
1624     }
1625 
1626     for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) {
1627         Stage1ZirInst *input_value = input_list[i];
1628         ir_ref_instruction(input_value, ag->current_basic_block);
1629     }
1630 
1631     return &instruction->base;
1632 }
1633 
ir_build_size_of(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type_value,bool bit_size)1634 static Stage1ZirInst *ir_build_size_of(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *type_value,
1635         bool bit_size)
1636 {
1637     Stage1ZirInstSizeOf *instruction = ir_build_instruction<Stage1ZirInstSizeOf>(ag, scope, source_node);
1638     instruction->type_value = type_value;
1639     instruction->bit_size = bit_size;
1640 
1641     ir_ref_instruction(type_value, ag->current_basic_block);
1642 
1643     return &instruction->base;
1644 }
1645 
ir_build_test_non_null_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * value)1646 static Stage1ZirInst *ir_build_test_non_null_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1647         Stage1ZirInst *value)
1648 {
1649     Stage1ZirInstTestNonNull *instruction = ir_build_instruction<Stage1ZirInstTestNonNull>(ag, scope, source_node);
1650     instruction->value = value;
1651 
1652     ir_ref_instruction(value, ag->current_basic_block);
1653 
1654     return &instruction->base;
1655 }
1656 
ir_build_optional_unwrap_ptr(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * base_ptr,bool safety_check_on)1657 static Stage1ZirInst *ir_build_optional_unwrap_ptr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1658         Stage1ZirInst *base_ptr, bool safety_check_on)
1659 {
1660     Stage1ZirInstOptionalUnwrapPtr *instruction = ir_build_instruction<Stage1ZirInstOptionalUnwrapPtr>(ag, scope, source_node);
1661     instruction->base_ptr = base_ptr;
1662     instruction->safety_check_on = safety_check_on;
1663 
1664     ir_ref_instruction(base_ptr, ag->current_basic_block);
1665 
1666     return &instruction->base;
1667 }
1668 
ir_build_clz(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type,Stage1ZirInst * op)1669 static Stage1ZirInst *ir_build_clz(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *type,
1670         Stage1ZirInst *op)
1671 {
1672     Stage1ZirInstClz *instruction = ir_build_instruction<Stage1ZirInstClz>(ag, scope, source_node);
1673     instruction->type = type;
1674     instruction->op = op;
1675 
1676     ir_ref_instruction(type, ag->current_basic_block);
1677     ir_ref_instruction(op, ag->current_basic_block);
1678 
1679     return &instruction->base;
1680 }
1681 
ir_build_ctz(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type,Stage1ZirInst * op)1682 static Stage1ZirInst *ir_build_ctz(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *type,
1683         Stage1ZirInst *op)
1684 {
1685     Stage1ZirInstCtz *instruction = ir_build_instruction<Stage1ZirInstCtz>(ag, scope, source_node);
1686     instruction->type = type;
1687     instruction->op = op;
1688 
1689     ir_ref_instruction(type, ag->current_basic_block);
1690     ir_ref_instruction(op, ag->current_basic_block);
1691 
1692     return &instruction->base;
1693 }
1694 
ir_build_pop_count(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type,Stage1ZirInst * op)1695 static Stage1ZirInst *ir_build_pop_count(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *type,
1696         Stage1ZirInst *op)
1697 {
1698     Stage1ZirInstPopCount *instruction = ir_build_instruction<Stage1ZirInstPopCount>(ag, scope, source_node);
1699     instruction->type = type;
1700     instruction->op = op;
1701 
1702     ir_ref_instruction(type, ag->current_basic_block);
1703     ir_ref_instruction(op, ag->current_basic_block);
1704 
1705     return &instruction->base;
1706 }
1707 
ir_build_bswap(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type,Stage1ZirInst * op)1708 static Stage1ZirInst *ir_build_bswap(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *type,
1709         Stage1ZirInst *op)
1710 {
1711     Stage1ZirInstBswap *instruction = ir_build_instruction<Stage1ZirInstBswap>(ag, scope, source_node);
1712     instruction->type = type;
1713     instruction->op = op;
1714 
1715     ir_ref_instruction(type, ag->current_basic_block);
1716     ir_ref_instruction(op, ag->current_basic_block);
1717 
1718     return &instruction->base;
1719 }
1720 
ir_build_bit_reverse(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type,Stage1ZirInst * op)1721 static Stage1ZirInst *ir_build_bit_reverse(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *type,
1722         Stage1ZirInst *op)
1723 {
1724     Stage1ZirInstBitReverse *instruction = ir_build_instruction<Stage1ZirInstBitReverse>(ag, scope, source_node);
1725     instruction->type = type;
1726     instruction->op = op;
1727 
1728     ir_ref_instruction(type, ag->current_basic_block);
1729     ir_ref_instruction(op, ag->current_basic_block);
1730 
1731     return &instruction->base;
1732 }
1733 
ir_build_switch_br_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target_value,Stage1ZirBasicBlock * else_block,size_t case_count,Stage1ZirInstSwitchBrCase * cases,Stage1ZirInst * is_comptime,Stage1ZirInst * switch_prongs_void)1734 static Stage1ZirInstSwitchBr *ir_build_switch_br_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1735         Stage1ZirInst *target_value, Stage1ZirBasicBlock *else_block, size_t case_count, Stage1ZirInstSwitchBrCase *cases,
1736         Stage1ZirInst *is_comptime, Stage1ZirInst *switch_prongs_void)
1737 {
1738     Stage1ZirInstSwitchBr *instruction = ir_build_instruction<Stage1ZirInstSwitchBr>(ag, scope, source_node);
1739     instruction->target_value = target_value;
1740     instruction->else_block = else_block;
1741     instruction->case_count = case_count;
1742     instruction->cases = cases;
1743     instruction->is_comptime = is_comptime;
1744     instruction->switch_prongs_void = switch_prongs_void;
1745 
1746     ir_ref_instruction(target_value, ag->current_basic_block);
1747     ir_ref_instruction(is_comptime, ag->current_basic_block);
1748     ir_ref_bb(else_block);
1749     ir_ref_instruction(switch_prongs_void, ag->current_basic_block);
1750 
1751     for (size_t i = 0; i < case_count; i += 1) {
1752         ir_ref_instruction(cases[i].value, ag->current_basic_block);
1753         ir_ref_bb(cases[i].block);
1754     }
1755 
1756     return instruction;
1757 }
1758 
ir_build_switch_target(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target_value_ptr)1759 static Stage1ZirInst *ir_build_switch_target(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1760         Stage1ZirInst *target_value_ptr)
1761 {
1762     Stage1ZirInstSwitchTarget *instruction = ir_build_instruction<Stage1ZirInstSwitchTarget>(ag, scope, source_node);
1763     instruction->target_value_ptr = target_value_ptr;
1764 
1765     ir_ref_instruction(target_value_ptr, ag->current_basic_block);
1766 
1767     return &instruction->base;
1768 }
1769 
ir_build_switch_var(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target_value_ptr,Stage1ZirInst ** prongs_ptr,size_t prongs_len)1770 static Stage1ZirInst *ir_build_switch_var(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1771         Stage1ZirInst *target_value_ptr, Stage1ZirInst **prongs_ptr, size_t prongs_len)
1772 {
1773     Stage1ZirInstSwitchVar *instruction = ir_build_instruction<Stage1ZirInstSwitchVar>(ag, scope, source_node);
1774     instruction->target_value_ptr = target_value_ptr;
1775     instruction->prongs_ptr = prongs_ptr;
1776     instruction->prongs_len = prongs_len;
1777 
1778     ir_ref_instruction(target_value_ptr, ag->current_basic_block);
1779     for (size_t i = 0; i < prongs_len; i += 1) {
1780         ir_ref_instruction(prongs_ptr[i], ag->current_basic_block);
1781     }
1782 
1783     return &instruction->base;
1784 }
1785 
1786 // For this instruction the switch_br must be set later.
ir_build_switch_else_var(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target_value_ptr)1787 static Stage1ZirInstSwitchElseVar *ir_build_switch_else_var(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1788         Stage1ZirInst *target_value_ptr)
1789 {
1790     Stage1ZirInstSwitchElseVar *instruction = ir_build_instruction<Stage1ZirInstSwitchElseVar>(ag, scope, source_node);
1791     instruction->target_value_ptr = target_value_ptr;
1792 
1793     ir_ref_instruction(target_value_ptr, ag->current_basic_block);
1794 
1795     return instruction;
1796 }
1797 
ir_build_import(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * name)1798 static Stage1ZirInst *ir_build_import(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *name) {
1799     Stage1ZirInstImport *instruction = ir_build_instruction<Stage1ZirInstImport>(ag, scope, source_node);
1800     instruction->name = name;
1801 
1802     ir_ref_instruction(name, ag->current_basic_block);
1803 
1804     return &instruction->base;
1805 }
1806 
ir_build_ref_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * value)1807 static Stage1ZirInst *ir_build_ref_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *value) {
1808     Stage1ZirInstRef *instruction = ir_build_instruction<Stage1ZirInstRef>(ag, scope, source_node);
1809     instruction->value = value;
1810 
1811     ir_ref_instruction(value, ag->current_basic_block);
1812 
1813     return &instruction->base;
1814 }
1815 
ir_build_compile_err(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * msg)1816 static Stage1ZirInst *ir_build_compile_err(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *msg) {
1817     Stage1ZirInstCompileErr *instruction = ir_build_instruction<Stage1ZirInstCompileErr>(ag, scope, source_node);
1818     instruction->msg = msg;
1819 
1820     ir_ref_instruction(msg, ag->current_basic_block);
1821 
1822     return &instruction->base;
1823 }
1824 
ir_build_compile_log(Stage1AstGen * ag,Scope * scope,AstNode * source_node,size_t msg_count,Stage1ZirInst ** msg_list)1825 static Stage1ZirInst *ir_build_compile_log(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1826         size_t msg_count, Stage1ZirInst **msg_list)
1827 {
1828     Stage1ZirInstCompileLog *instruction = ir_build_instruction<Stage1ZirInstCompileLog>(ag, scope, source_node);
1829     instruction->msg_count = msg_count;
1830     instruction->msg_list = msg_list;
1831 
1832     for (size_t i = 0; i < msg_count; i += 1) {
1833         ir_ref_instruction(msg_list[i], ag->current_basic_block);
1834     }
1835 
1836     return &instruction->base;
1837 }
1838 
ir_build_err_name(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * value)1839 static Stage1ZirInst *ir_build_err_name(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *value) {
1840     Stage1ZirInstErrName *instruction = ir_build_instruction<Stage1ZirInstErrName>(ag, scope, source_node);
1841     instruction->value = value;
1842 
1843     ir_ref_instruction(value, ag->current_basic_block);
1844 
1845     return &instruction->base;
1846 }
1847 
ir_build_c_import(Stage1AstGen * ag,Scope * scope,AstNode * source_node)1848 static Stage1ZirInst *ir_build_c_import(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
1849     Stage1ZirInstCImport *instruction = ir_build_instruction<Stage1ZirInstCImport>(ag, scope, source_node);
1850     return &instruction->base;
1851 }
1852 
ir_build_c_include(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * name)1853 static Stage1ZirInst *ir_build_c_include(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *name) {
1854     Stage1ZirInstCInclude *instruction = ir_build_instruction<Stage1ZirInstCInclude>(ag, scope, source_node);
1855     instruction->name = name;
1856 
1857     ir_ref_instruction(name, ag->current_basic_block);
1858 
1859     return &instruction->base;
1860 }
1861 
ir_build_c_define(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * name,Stage1ZirInst * value)1862 static Stage1ZirInst *ir_build_c_define(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *name, Stage1ZirInst *value) {
1863     Stage1ZirInstCDefine *instruction = ir_build_instruction<Stage1ZirInstCDefine>(ag, scope, source_node);
1864     instruction->name = name;
1865     instruction->value = value;
1866 
1867     ir_ref_instruction(name, ag->current_basic_block);
1868     ir_ref_instruction(value, ag->current_basic_block);
1869 
1870     return &instruction->base;
1871 }
1872 
ir_build_c_undef(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * name)1873 static Stage1ZirInst *ir_build_c_undef(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *name) {
1874     Stage1ZirInstCUndef *instruction = ir_build_instruction<Stage1ZirInstCUndef>(ag, scope, source_node);
1875     instruction->name = name;
1876 
1877     ir_ref_instruction(name, ag->current_basic_block);
1878 
1879     return &instruction->base;
1880 }
1881 
ir_build_embed_file(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * name)1882 static Stage1ZirInst *ir_build_embed_file(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *name) {
1883     Stage1ZirInstEmbedFile *instruction = ir_build_instruction<Stage1ZirInstEmbedFile>(ag, scope, source_node);
1884     instruction->name = name;
1885 
1886     ir_ref_instruction(name, ag->current_basic_block);
1887 
1888     return &instruction->base;
1889 }
1890 
ir_build_cmpxchg_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type_value,Stage1ZirInst * ptr,Stage1ZirInst * cmp_value,Stage1ZirInst * new_value,Stage1ZirInst * success_order_value,Stage1ZirInst * failure_order_value,bool is_weak,ResultLoc * result_loc)1891 static Stage1ZirInst *ir_build_cmpxchg_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1892     Stage1ZirInst *type_value, Stage1ZirInst *ptr, Stage1ZirInst *cmp_value, Stage1ZirInst *new_value,
1893     Stage1ZirInst *success_order_value, Stage1ZirInst *failure_order_value, bool is_weak, ResultLoc *result_loc)
1894 {
1895     Stage1ZirInstCmpxchg *instruction = ir_build_instruction<Stage1ZirInstCmpxchg>(ag, scope, source_node);
1896     instruction->type_value = type_value;
1897     instruction->ptr = ptr;
1898     instruction->cmp_value = cmp_value;
1899     instruction->new_value = new_value;
1900     instruction->success_order_value = success_order_value;
1901     instruction->failure_order_value = failure_order_value;
1902     instruction->is_weak = is_weak;
1903     instruction->result_loc = result_loc;
1904 
1905     ir_ref_instruction(type_value, ag->current_basic_block);
1906     ir_ref_instruction(ptr, ag->current_basic_block);
1907     ir_ref_instruction(cmp_value, ag->current_basic_block);
1908     ir_ref_instruction(new_value, ag->current_basic_block);
1909     ir_ref_instruction(success_order_value, ag->current_basic_block);
1910     ir_ref_instruction(failure_order_value, ag->current_basic_block);
1911 
1912     return &instruction->base;
1913 }
1914 
ir_build_fence(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * order)1915 static Stage1ZirInst *ir_build_fence(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *order) {
1916     Stage1ZirInstFence *instruction = ir_build_instruction<Stage1ZirInstFence>(ag, scope, source_node);
1917     instruction->order = order;
1918 
1919     ir_ref_instruction(order, ag->current_basic_block);
1920 
1921     return &instruction->base;
1922 }
1923 
ir_build_reduce(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * op,Stage1ZirInst * value)1924 static Stage1ZirInst *ir_build_reduce(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *op, Stage1ZirInst *value) {
1925     Stage1ZirInstReduce *instruction = ir_build_instruction<Stage1ZirInstReduce>(ag, scope, source_node);
1926     instruction->op = op;
1927     instruction->value = value;
1928 
1929     ir_ref_instruction(op, ag->current_basic_block);
1930     ir_ref_instruction(value, ag->current_basic_block);
1931 
1932     return &instruction->base;
1933 }
1934 
ir_build_truncate(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * dest_type,Stage1ZirInst * target)1935 static Stage1ZirInst *ir_build_truncate(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1936         Stage1ZirInst *dest_type, Stage1ZirInst *target)
1937 {
1938     Stage1ZirInstTruncate *instruction = ir_build_instruction<Stage1ZirInstTruncate>(ag, scope, source_node);
1939     instruction->dest_type = dest_type;
1940     instruction->target = target;
1941 
1942     ir_ref_instruction(dest_type, ag->current_basic_block);
1943     ir_ref_instruction(target, ag->current_basic_block);
1944 
1945     return &instruction->base;
1946 }
1947 
ir_build_int_cast(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * dest_type,Stage1ZirInst * target)1948 static Stage1ZirInst *ir_build_int_cast(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *dest_type,
1949         Stage1ZirInst *target)
1950 {
1951     Stage1ZirInstIntCast *instruction = ir_build_instruction<Stage1ZirInstIntCast>(ag, scope, source_node);
1952     instruction->dest_type = dest_type;
1953     instruction->target = target;
1954 
1955     ir_ref_instruction(dest_type, ag->current_basic_block);
1956     ir_ref_instruction(target, ag->current_basic_block);
1957 
1958     return &instruction->base;
1959 }
1960 
ir_build_float_cast(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * dest_type,Stage1ZirInst * target)1961 static Stage1ZirInst *ir_build_float_cast(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *dest_type,
1962         Stage1ZirInst *target)
1963 {
1964     Stage1ZirInstFloatCast *instruction = ir_build_instruction<Stage1ZirInstFloatCast>(ag, scope, source_node);
1965     instruction->dest_type = dest_type;
1966     instruction->target = target;
1967 
1968     ir_ref_instruction(dest_type, ag->current_basic_block);
1969     ir_ref_instruction(target, ag->current_basic_block);
1970 
1971     return &instruction->base;
1972 }
1973 
ir_build_err_set_cast(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * dest_type,Stage1ZirInst * target)1974 static Stage1ZirInst *ir_build_err_set_cast(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1975         Stage1ZirInst *dest_type, Stage1ZirInst *target)
1976 {
1977     Stage1ZirInstErrSetCast *instruction = ir_build_instruction<Stage1ZirInstErrSetCast>(ag, scope, source_node);
1978     instruction->dest_type = dest_type;
1979     instruction->target = target;
1980 
1981     ir_ref_instruction(dest_type, ag->current_basic_block);
1982     ir_ref_instruction(target, ag->current_basic_block);
1983 
1984     return &instruction->base;
1985 }
1986 
ir_build_int_to_float(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * dest_type,Stage1ZirInst * target)1987 static Stage1ZirInst *ir_build_int_to_float(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
1988         Stage1ZirInst *dest_type, Stage1ZirInst *target)
1989 {
1990     Stage1ZirInstIntToFloat *instruction = ir_build_instruction<Stage1ZirInstIntToFloat>(ag, scope, source_node);
1991     instruction->dest_type = dest_type;
1992     instruction->target = target;
1993 
1994     ir_ref_instruction(dest_type, ag->current_basic_block);
1995     ir_ref_instruction(target, ag->current_basic_block);
1996 
1997     return &instruction->base;
1998 }
1999 
ir_build_float_to_int(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * dest_type,Stage1ZirInst * target)2000 static Stage1ZirInst *ir_build_float_to_int(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2001         Stage1ZirInst *dest_type, Stage1ZirInst *target)
2002 {
2003     Stage1ZirInstFloatToInt *instruction = ir_build_instruction<Stage1ZirInstFloatToInt>(ag, scope, source_node);
2004     instruction->dest_type = dest_type;
2005     instruction->target = target;
2006 
2007     ir_ref_instruction(dest_type, ag->current_basic_block);
2008     ir_ref_instruction(target, ag->current_basic_block);
2009 
2010     return &instruction->base;
2011 }
2012 
ir_build_bool_to_int(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target)2013 static Stage1ZirInst *ir_build_bool_to_int(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *target) {
2014     Stage1ZirInstBoolToInt *instruction = ir_build_instruction<Stage1ZirInstBoolToInt>(ag, scope, source_node);
2015     instruction->target = target;
2016 
2017     ir_ref_instruction(target, ag->current_basic_block);
2018 
2019     return &instruction->base;
2020 }
2021 
ir_build_vector_type(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * len,Stage1ZirInst * elem_type)2022 static Stage1ZirInst *ir_build_vector_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *len,
2023         Stage1ZirInst *elem_type)
2024 {
2025     Stage1ZirInstVectorType *instruction = ir_build_instruction<Stage1ZirInstVectorType>(ag, scope, source_node);
2026     instruction->len = len;
2027     instruction->elem_type = elem_type;
2028 
2029     ir_ref_instruction(len, ag->current_basic_block);
2030     ir_ref_instruction(elem_type, ag->current_basic_block);
2031 
2032     return &instruction->base;
2033 }
2034 
ir_build_shuffle_vector(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * scalar_type,Stage1ZirInst * a,Stage1ZirInst * b,Stage1ZirInst * mask)2035 static Stage1ZirInst *ir_build_shuffle_vector(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2036     Stage1ZirInst *scalar_type, Stage1ZirInst *a, Stage1ZirInst *b, Stage1ZirInst *mask)
2037 {
2038     Stage1ZirInstShuffleVector *instruction = ir_build_instruction<Stage1ZirInstShuffleVector>(ag, scope, source_node);
2039     instruction->scalar_type = scalar_type;
2040     instruction->a = a;
2041     instruction->b = b;
2042     instruction->mask = mask;
2043 
2044     if (scalar_type != nullptr) ir_ref_instruction(scalar_type, ag->current_basic_block);
2045     ir_ref_instruction(a, ag->current_basic_block);
2046     ir_ref_instruction(b, ag->current_basic_block);
2047     ir_ref_instruction(mask, ag->current_basic_block);
2048 
2049     return &instruction->base;
2050 }
2051 
ir_build_select(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * scalar_type,Stage1ZirInst * pred,Stage1ZirInst * a,Stage1ZirInst * b)2052 static Stage1ZirInst *ir_build_select(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2053     Stage1ZirInst *scalar_type, Stage1ZirInst *pred, Stage1ZirInst *a, Stage1ZirInst *b)
2054 {
2055     Stage1ZirInstSelect *instruction = ir_build_instruction<Stage1ZirInstSelect>(ag, scope, source_node);
2056     instruction->scalar_type = scalar_type;
2057     instruction->pred = pred;
2058     instruction->a = a;
2059     instruction->b = b;
2060 
2061     ir_ref_instruction(pred, ag->current_basic_block);
2062     ir_ref_instruction(a, ag->current_basic_block);
2063     ir_ref_instruction(b, ag->current_basic_block);
2064 
2065     return &instruction->base;
2066 }
2067 
ir_build_splat_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * len,Stage1ZirInst * scalar)2068 static Stage1ZirInst *ir_build_splat_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2069     Stage1ZirInst *len, Stage1ZirInst *scalar)
2070 {
2071     Stage1ZirInstSplat *instruction = ir_build_instruction<Stage1ZirInstSplat>(ag, scope, source_node);
2072     instruction->len = len;
2073     instruction->scalar = scalar;
2074 
2075     ir_ref_instruction(len, ag->current_basic_block);
2076     ir_ref_instruction(scalar, ag->current_basic_block);
2077 
2078     return &instruction->base;
2079 }
2080 
ir_build_bool_not(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * value)2081 static Stage1ZirInst *ir_build_bool_not(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *value) {
2082     Stage1ZirInstBoolNot *instruction = ir_build_instruction<Stage1ZirInstBoolNot>(ag, scope, source_node);
2083     instruction->value = value;
2084 
2085     ir_ref_instruction(value, ag->current_basic_block);
2086 
2087     return &instruction->base;
2088 }
2089 
ir_build_memset_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * dest_ptr,Stage1ZirInst * byte,Stage1ZirInst * count)2090 static Stage1ZirInst *ir_build_memset_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2091     Stage1ZirInst *dest_ptr, Stage1ZirInst *byte, Stage1ZirInst *count)
2092 {
2093     Stage1ZirInstMemset *instruction = ir_build_instruction<Stage1ZirInstMemset>(ag, scope, source_node);
2094     instruction->dest_ptr = dest_ptr;
2095     instruction->byte = byte;
2096     instruction->count = count;
2097 
2098     ir_ref_instruction(dest_ptr, ag->current_basic_block);
2099     ir_ref_instruction(byte, ag->current_basic_block);
2100     ir_ref_instruction(count, ag->current_basic_block);
2101 
2102     return &instruction->base;
2103 }
2104 
ir_build_memcpy_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * dest_ptr,Stage1ZirInst * src_ptr,Stage1ZirInst * count)2105 static Stage1ZirInst *ir_build_memcpy_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2106     Stage1ZirInst *dest_ptr, Stage1ZirInst *src_ptr, Stage1ZirInst *count)
2107 {
2108     Stage1ZirInstMemcpy *instruction = ir_build_instruction<Stage1ZirInstMemcpy>(ag, scope, source_node);
2109     instruction->dest_ptr = dest_ptr;
2110     instruction->src_ptr = src_ptr;
2111     instruction->count = count;
2112 
2113     ir_ref_instruction(dest_ptr, ag->current_basic_block);
2114     ir_ref_instruction(src_ptr, ag->current_basic_block);
2115     ir_ref_instruction(count, ag->current_basic_block);
2116 
2117     return &instruction->base;
2118 }
2119 
ir_build_slice_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * ptr,Stage1ZirInst * start,Stage1ZirInst * end,Stage1ZirInst * sentinel,bool safety_check_on,ResultLoc * result_loc)2120 static Stage1ZirInst *ir_build_slice_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2121     Stage1ZirInst *ptr, Stage1ZirInst *start, Stage1ZirInst *end, Stage1ZirInst *sentinel,
2122     bool safety_check_on, ResultLoc *result_loc)
2123 {
2124     Stage1ZirInstSlice *instruction = ir_build_instruction<Stage1ZirInstSlice>(ag, scope, source_node);
2125     instruction->ptr = ptr;
2126     instruction->start = start;
2127     instruction->end = end;
2128     instruction->sentinel = sentinel;
2129     instruction->safety_check_on = safety_check_on;
2130     instruction->result_loc = result_loc;
2131 
2132     ir_ref_instruction(ptr, ag->current_basic_block);
2133     ir_ref_instruction(start, ag->current_basic_block);
2134     if (end) ir_ref_instruction(end, ag->current_basic_block);
2135     if (sentinel) ir_ref_instruction(sentinel, ag->current_basic_block);
2136 
2137     return &instruction->base;
2138 }
2139 
ir_build_breakpoint(Stage1AstGen * ag,Scope * scope,AstNode * source_node)2140 static Stage1ZirInst *ir_build_breakpoint(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2141     Stage1ZirInstBreakpoint *instruction = ir_build_instruction<Stage1ZirInstBreakpoint>(ag, scope, source_node);
2142     return &instruction->base;
2143 }
2144 
ir_build_return_address_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node)2145 static Stage1ZirInst *ir_build_return_address_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2146     Stage1ZirInstReturnAddress *instruction = ir_build_instruction<Stage1ZirInstReturnAddress>(ag, scope, source_node);
2147     return &instruction->base;
2148 }
2149 
ir_build_frame_address_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node)2150 static Stage1ZirInst *ir_build_frame_address_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2151     Stage1ZirInstFrameAddress *inst = ir_build_instruction<Stage1ZirInstFrameAddress>(ag, scope, source_node);
2152     return &inst->base;
2153 }
2154 
ir_build_handle_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node)2155 static Stage1ZirInst *ir_build_handle_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2156     Stage1ZirInstFrameHandle *inst = ir_build_instruction<Stage1ZirInstFrameHandle>(ag, scope, source_node);
2157     return &inst->base;
2158 }
2159 
ir_build_frame_type(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * fn)2160 static Stage1ZirInst *ir_build_frame_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *fn) {
2161     Stage1ZirInstFrameType *inst = ir_build_instruction<Stage1ZirInstFrameType>(ag, scope, source_node);
2162     inst->fn = fn;
2163 
2164     ir_ref_instruction(fn, ag->current_basic_block);
2165 
2166     return &inst->base;
2167 }
2168 
ir_build_frame_size_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * fn)2169 static Stage1ZirInst *ir_build_frame_size_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *fn) {
2170     Stage1ZirInstFrameSize *inst = ir_build_instruction<Stage1ZirInstFrameSize>(ag, scope, source_node);
2171     inst->fn = fn;
2172 
2173     ir_ref_instruction(fn, ag->current_basic_block);
2174 
2175     return &inst->base;
2176 }
2177 
ir_build_overflow_op_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,IrOverflowOp op,Stage1ZirInst * type_value,Stage1ZirInst * op1,Stage1ZirInst * op2,Stage1ZirInst * result_ptr)2178 static Stage1ZirInst *ir_build_overflow_op_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2179         IrOverflowOp op, Stage1ZirInst *type_value, Stage1ZirInst *op1, Stage1ZirInst *op2, Stage1ZirInst *result_ptr)
2180 {
2181     Stage1ZirInstOverflowOp *instruction = ir_build_instruction<Stage1ZirInstOverflowOp>(ag, scope, source_node);
2182     instruction->op = op;
2183     instruction->type_value = type_value;
2184     instruction->op1 = op1;
2185     instruction->op2 = op2;
2186     instruction->result_ptr = result_ptr;
2187 
2188     ir_ref_instruction(type_value, ag->current_basic_block);
2189     ir_ref_instruction(op1, ag->current_basic_block);
2190     ir_ref_instruction(op2, ag->current_basic_block);
2191     ir_ref_instruction(result_ptr, ag->current_basic_block);
2192 
2193     return &instruction->base;
2194 }
2195 
ir_build_float_op_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * operand,BuiltinFnId fn_id)2196 static Stage1ZirInst *ir_build_float_op_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *operand,
2197         BuiltinFnId fn_id)
2198 {
2199     Stage1ZirInstFloatOp *instruction = ir_build_instruction<Stage1ZirInstFloatOp>(ag, scope, source_node);
2200     instruction->operand = operand;
2201     instruction->fn_id = fn_id;
2202 
2203     ir_ref_instruction(operand, ag->current_basic_block);
2204 
2205     return &instruction->base;
2206 }
2207 
ir_build_mul_add_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type_value,Stage1ZirInst * op1,Stage1ZirInst * op2,Stage1ZirInst * op3)2208 static Stage1ZirInst *ir_build_mul_add_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2209         Stage1ZirInst *type_value, Stage1ZirInst *op1, Stage1ZirInst *op2, Stage1ZirInst *op3)
2210 {
2211     Stage1ZirInstMulAdd *instruction = ir_build_instruction<Stage1ZirInstMulAdd>(ag, scope, source_node);
2212     instruction->type_value = type_value;
2213     instruction->op1 = op1;
2214     instruction->op2 = op2;
2215     instruction->op3 = op3;
2216 
2217     ir_ref_instruction(type_value, ag->current_basic_block);
2218     ir_ref_instruction(op1, ag->current_basic_block);
2219     ir_ref_instruction(op2, ag->current_basic_block);
2220     ir_ref_instruction(op3, ag->current_basic_block);
2221 
2222     return &instruction->base;
2223 }
2224 
ir_build_align_of(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type_value)2225 static Stage1ZirInst *ir_build_align_of(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *type_value) {
2226     Stage1ZirInstAlignOf *instruction = ir_build_instruction<Stage1ZirInstAlignOf>(ag, scope, source_node);
2227     instruction->type_value = type_value;
2228 
2229     ir_ref_instruction(type_value, ag->current_basic_block);
2230 
2231     return &instruction->base;
2232 }
2233 
ir_build_test_err_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * base_ptr,bool resolve_err_set,bool base_ptr_is_payload)2234 static Stage1ZirInst *ir_build_test_err_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2235     Stage1ZirInst *base_ptr, bool resolve_err_set, bool base_ptr_is_payload)
2236 {
2237     Stage1ZirInstTestErr *instruction = ir_build_instruction<Stage1ZirInstTestErr>(ag, scope, source_node);
2238     instruction->base_ptr = base_ptr;
2239     instruction->resolve_err_set = resolve_err_set;
2240     instruction->base_ptr_is_payload = base_ptr_is_payload;
2241 
2242     ir_ref_instruction(base_ptr, ag->current_basic_block);
2243 
2244     return &instruction->base;
2245 }
2246 
ir_build_unwrap_err_code_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * err_union_ptr)2247 static Stage1ZirInst *ir_build_unwrap_err_code_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2248     Stage1ZirInst *err_union_ptr)
2249 {
2250     Stage1ZirInstUnwrapErrCode *inst = ir_build_instruction<Stage1ZirInstUnwrapErrCode>(ag, scope, source_node);
2251     inst->err_union_ptr = err_union_ptr;
2252 
2253     ir_ref_instruction(err_union_ptr, ag->current_basic_block);
2254 
2255     return &inst->base;
2256 }
2257 
ir_build_unwrap_err_payload_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * value,bool safety_check_on,bool initializing)2258 static Stage1ZirInst *ir_build_unwrap_err_payload_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2259     Stage1ZirInst *value, bool safety_check_on, bool initializing)
2260 {
2261     Stage1ZirInstUnwrapErrPayload *inst = ir_build_instruction<Stage1ZirInstUnwrapErrPayload>(ag, scope, source_node);
2262     inst->value = value;
2263     inst->safety_check_on = safety_check_on;
2264     inst->initializing = initializing;
2265 
2266     ir_ref_instruction(value, ag->current_basic_block);
2267 
2268     return &inst->base;
2269 }
2270 
ir_build_fn_proto(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst ** param_types,Stage1ZirInst * align_value,Stage1ZirInst * callconv_value,Stage1ZirInst * return_type,bool is_var_args)2271 static Stage1ZirInst *ir_build_fn_proto(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2272     Stage1ZirInst **param_types, Stage1ZirInst *align_value, Stage1ZirInst *callconv_value,
2273     Stage1ZirInst *return_type, bool is_var_args)
2274 {
2275     Stage1ZirInstFnProto *instruction = ir_build_instruction<Stage1ZirInstFnProto>(ag, scope, source_node);
2276     instruction->param_types = param_types;
2277     instruction->align_value = align_value;
2278     instruction->callconv_value = callconv_value;
2279     instruction->return_type = return_type;
2280     instruction->is_var_args = is_var_args;
2281 
2282     assert(source_node->type == NodeTypeFnProto);
2283     size_t param_count = source_node->data.fn_proto.params.length;
2284     if (is_var_args) param_count -= 1;
2285     for (size_t i = 0; i < param_count; i += 1) {
2286         if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], ag->current_basic_block);
2287     }
2288     if (align_value != nullptr) ir_ref_instruction(align_value, ag->current_basic_block);
2289     if (callconv_value != nullptr) ir_ref_instruction(callconv_value, ag->current_basic_block);
2290     ir_ref_instruction(return_type, ag->current_basic_block);
2291 
2292     return &instruction->base;
2293 }
2294 
ir_build_test_comptime(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * value)2295 static Stage1ZirInst *ir_build_test_comptime(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *value) {
2296     Stage1ZirInstTestComptime *instruction = ir_build_instruction<Stage1ZirInstTestComptime>(ag, scope, source_node);
2297     instruction->value = value;
2298 
2299     ir_ref_instruction(value, ag->current_basic_block);
2300 
2301     return &instruction->base;
2302 }
2303 
ir_build_ptr_cast_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * dest_type,Stage1ZirInst * ptr,bool safety_check_on)2304 static Stage1ZirInst *ir_build_ptr_cast_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2305         Stage1ZirInst *dest_type, Stage1ZirInst *ptr, bool safety_check_on)
2306 {
2307     Stage1ZirInstPtrCast *instruction = ir_build_instruction<Stage1ZirInstPtrCast>(
2308             ag, scope, source_node);
2309     instruction->dest_type = dest_type;
2310     instruction->ptr = ptr;
2311     instruction->safety_check_on = safety_check_on;
2312 
2313     ir_ref_instruction(dest_type, ag->current_basic_block);
2314     ir_ref_instruction(ptr, ag->current_basic_block);
2315 
2316     return &instruction->base;
2317 }
2318 
ir_build_implicit_cast(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * operand,ResultLocCast * result_loc_cast)2319 static Stage1ZirInst *ir_build_implicit_cast(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2320         Stage1ZirInst *operand, ResultLocCast *result_loc_cast)
2321 {
2322     Stage1ZirInstImplicitCast *instruction = ir_build_instruction<Stage1ZirInstImplicitCast>(ag, scope, source_node);
2323     instruction->operand = operand;
2324     instruction->result_loc_cast = result_loc_cast;
2325 
2326     ir_ref_instruction(operand, ag->current_basic_block);
2327 
2328     return &instruction->base;
2329 }
2330 
ir_build_bit_cast_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * operand,ResultLocBitCast * result_loc_bit_cast)2331 static Stage1ZirInst *ir_build_bit_cast_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2332         Stage1ZirInst *operand, ResultLocBitCast *result_loc_bit_cast)
2333 {
2334     Stage1ZirInstBitCast *instruction = ir_build_instruction<Stage1ZirInstBitCast>(ag, scope, source_node);
2335     instruction->operand = operand;
2336     instruction->result_loc_bit_cast = result_loc_bit_cast;
2337 
2338     ir_ref_instruction(operand, ag->current_basic_block);
2339 
2340     return &instruction->base;
2341 }
2342 
ir_build_int_to_ptr_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * dest_type,Stage1ZirInst * target)2343 static Stage1ZirInst *ir_build_int_to_ptr_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2344         Stage1ZirInst *dest_type, Stage1ZirInst *target)
2345 {
2346     Stage1ZirInstIntToPtr *instruction = ir_build_instruction<Stage1ZirInstIntToPtr>(ag, scope, source_node);
2347     instruction->dest_type = dest_type;
2348     instruction->target = target;
2349 
2350     ir_ref_instruction(dest_type, ag->current_basic_block);
2351     ir_ref_instruction(target, ag->current_basic_block);
2352 
2353     return &instruction->base;
2354 }
2355 
ir_build_ptr_to_int_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target)2356 static Stage1ZirInst *ir_build_ptr_to_int_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2357         Stage1ZirInst *target)
2358 {
2359     Stage1ZirInstPtrToInt *inst = ir_build_instruction<Stage1ZirInstPtrToInt>(ag, scope, source_node);
2360     inst->target = target;
2361 
2362     ir_ref_instruction(target, ag->current_basic_block);
2363 
2364     return &inst->base;
2365 }
2366 
ir_build_int_to_enum_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * dest_type,Stage1ZirInst * target)2367 static Stage1ZirInst *ir_build_int_to_enum_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2368         Stage1ZirInst *dest_type, Stage1ZirInst *target)
2369 {
2370     Stage1ZirInstIntToEnum *instruction = ir_build_instruction<Stage1ZirInstIntToEnum>(ag, scope, source_node);
2371     instruction->dest_type = dest_type;
2372     instruction->target = target;
2373 
2374     if (dest_type) ir_ref_instruction(dest_type, ag->current_basic_block);
2375     ir_ref_instruction(target, ag->current_basic_block);
2376 
2377     return &instruction->base;
2378 }
2379 
ir_build_enum_to_int(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target)2380 static Stage1ZirInst *ir_build_enum_to_int(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2381         Stage1ZirInst *target)
2382 {
2383     Stage1ZirInstEnumToInt *instruction = ir_build_instruction<Stage1ZirInstEnumToInt>(
2384             ag, scope, source_node);
2385     instruction->target = target;
2386 
2387     ir_ref_instruction(target, ag->current_basic_block);
2388 
2389     return &instruction->base;
2390 }
2391 
ir_build_int_to_err_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target)2392 static Stage1ZirInst *ir_build_int_to_err_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2393         Stage1ZirInst *target)
2394 {
2395     Stage1ZirInstIntToErr *instruction = ir_build_instruction<Stage1ZirInstIntToErr>(ag, scope, source_node);
2396     instruction->target = target;
2397 
2398     ir_ref_instruction(target, ag->current_basic_block);
2399 
2400     return &instruction->base;
2401 }
2402 
ir_build_err_to_int_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target)2403 static Stage1ZirInst *ir_build_err_to_int_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2404         Stage1ZirInst *target)
2405 {
2406     Stage1ZirInstErrToInt *instruction = ir_build_instruction<Stage1ZirInstErrToInt>(
2407             ag, scope, source_node);
2408     instruction->target = target;
2409 
2410     ir_ref_instruction(target, ag->current_basic_block);
2411 
2412     return &instruction->base;
2413 }
2414 
ir_build_check_switch_prongs(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target_value,Stage1ZirInstCheckSwitchProngsRange * ranges,size_t range_count,AstNode * else_prong,bool have_underscore_prong)2415 static Stage1ZirInst *ir_build_check_switch_prongs(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2416         Stage1ZirInst *target_value, Stage1ZirInstCheckSwitchProngsRange *ranges, size_t range_count,
2417         AstNode* else_prong, bool have_underscore_prong)
2418 {
2419     Stage1ZirInstCheckSwitchProngs *instruction = heap::c_allocator.create<Stage1ZirInstCheckSwitchProngs>();
2420     instruction->base.id = have_underscore_prong ?
2421         Stage1ZirInstIdCheckSwitchProngsUnderYes : Stage1ZirInstIdCheckSwitchProngsUnderNo;
2422     instruction->base.scope = scope;
2423     instruction->base.source_node = source_node;
2424     instruction->base.debug_id = irb_next_debug_id(ag);
2425     instruction->base.owner_bb = ag->current_basic_block;
2426     ir_instruction_append(ag->current_basic_block, &instruction->base);
2427 
2428     instruction->target_value = target_value;
2429     instruction->ranges = ranges;
2430     instruction->range_count = range_count;
2431     instruction->else_prong = else_prong;
2432 
2433     ir_ref_instruction(target_value, ag->current_basic_block);
2434     for (size_t i = 0; i < range_count; i += 1) {
2435         ir_ref_instruction(ranges[i].start, ag->current_basic_block);
2436         ir_ref_instruction(ranges[i].end, ag->current_basic_block);
2437     }
2438 
2439     return &instruction->base;
2440 }
2441 
ir_build_check_statement_is_void(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * statement_value)2442 static Stage1ZirInst *ir_build_check_statement_is_void(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2443     Stage1ZirInst* statement_value)
2444 {
2445     Stage1ZirInstCheckStatementIsVoid *instruction = ir_build_instruction<Stage1ZirInstCheckStatementIsVoid>(
2446             ag, scope, source_node);
2447     instruction->statement_value = statement_value;
2448 
2449     ir_ref_instruction(statement_value, ag->current_basic_block);
2450 
2451     return &instruction->base;
2452 }
2453 
ir_build_type_name(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type_value)2454 static Stage1ZirInst *ir_build_type_name(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2455         Stage1ZirInst *type_value)
2456 {
2457     Stage1ZirInstTypeName *instruction = ir_build_instruction<Stage1ZirInstTypeName>(ag, scope, source_node);
2458     instruction->type_value = type_value;
2459 
2460     ir_ref_instruction(type_value, ag->current_basic_block);
2461 
2462     return &instruction->base;
2463 }
2464 
ir_build_decl_ref(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Tld * tld,LVal lval)2465 static Stage1ZirInst *ir_build_decl_ref(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Tld *tld, LVal lval) {
2466     Stage1ZirInstDeclRef *instruction = ir_build_instruction<Stage1ZirInstDeclRef>(ag, scope, source_node);
2467     instruction->tld = tld;
2468     instruction->lval = lval;
2469 
2470     return &instruction->base;
2471 }
2472 
ir_build_panic_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * msg)2473 static Stage1ZirInst *ir_build_panic_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *msg) {
2474     Stage1ZirInstPanic *instruction = ir_build_instruction<Stage1ZirInstPanic>(ag, scope, source_node);
2475     instruction->msg = msg;
2476 
2477     ir_ref_instruction(msg, ag->current_basic_block);
2478 
2479     return &instruction->base;
2480 }
2481 
ir_build_tag_name_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * target)2482 static Stage1ZirInst *ir_build_tag_name_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *target) {
2483     Stage1ZirInstTagName *instruction = ir_build_instruction<Stage1ZirInstTagName>(ag, scope, source_node);
2484     instruction->target = target;
2485 
2486     ir_ref_instruction(target, ag->current_basic_block);
2487 
2488     return &instruction->base;
2489 }
2490 
ir_build_field_parent_ptr_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type_value,Stage1ZirInst * field_name,Stage1ZirInst * field_ptr)2491 static Stage1ZirInst *ir_build_field_parent_ptr_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2492         Stage1ZirInst *type_value, Stage1ZirInst *field_name, Stage1ZirInst *field_ptr)
2493 {
2494     Stage1ZirInstFieldParentPtr *inst = ir_build_instruction<Stage1ZirInstFieldParentPtr>(
2495             ag, scope, source_node);
2496     inst->type_value = type_value;
2497     inst->field_name = field_name;
2498     inst->field_ptr = field_ptr;
2499 
2500     ir_ref_instruction(type_value, ag->current_basic_block);
2501     ir_ref_instruction(field_name, ag->current_basic_block);
2502     ir_ref_instruction(field_ptr, ag->current_basic_block);
2503 
2504     return &inst->base;
2505 }
2506 
ir_build_offset_of(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type_value,Stage1ZirInst * field_name)2507 static Stage1ZirInst *ir_build_offset_of(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2508         Stage1ZirInst *type_value, Stage1ZirInst *field_name)
2509 {
2510     Stage1ZirInstOffsetOf *instruction = ir_build_instruction<Stage1ZirInstOffsetOf>(ag, scope, source_node);
2511     instruction->type_value = type_value;
2512     instruction->field_name = field_name;
2513 
2514     ir_ref_instruction(type_value, ag->current_basic_block);
2515     ir_ref_instruction(field_name, ag->current_basic_block);
2516 
2517     return &instruction->base;
2518 }
2519 
ir_build_bit_offset_of(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type_value,Stage1ZirInst * field_name)2520 static Stage1ZirInst *ir_build_bit_offset_of(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2521         Stage1ZirInst *type_value, Stage1ZirInst *field_name)
2522 {
2523     Stage1ZirInstBitOffsetOf *instruction = ir_build_instruction<Stage1ZirInstBitOffsetOf>(ag, scope, source_node);
2524     instruction->type_value = type_value;
2525     instruction->field_name = field_name;
2526 
2527     ir_ref_instruction(type_value, ag->current_basic_block);
2528     ir_ref_instruction(field_name, ag->current_basic_block);
2529 
2530     return &instruction->base;
2531 }
2532 
ir_build_type_info(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type_value)2533 static Stage1ZirInst *ir_build_type_info(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *type_value) {
2534     Stage1ZirInstTypeInfo *instruction = ir_build_instruction<Stage1ZirInstTypeInfo>(ag, scope, source_node);
2535     instruction->type_value = type_value;
2536 
2537     ir_ref_instruction(type_value, ag->current_basic_block);
2538 
2539     return &instruction->base;
2540 }
2541 
ir_build_type(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * type_info)2542 static Stage1ZirInst *ir_build_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *type_info) {
2543     Stage1ZirInstType *instruction = ir_build_instruction<Stage1ZirInstType>(ag, scope, source_node);
2544     instruction->type_info = type_info;
2545 
2546     ir_ref_instruction(type_info, ag->current_basic_block);
2547 
2548     return &instruction->base;
2549 }
2550 
ir_build_set_eval_branch_quota(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * new_quota)2551 static Stage1ZirInst *ir_build_set_eval_branch_quota(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2552         Stage1ZirInst *new_quota)
2553 {
2554     Stage1ZirInstSetEvalBranchQuota *instruction = ir_build_instruction<Stage1ZirInstSetEvalBranchQuota>(ag, scope, source_node);
2555     instruction->new_quota = new_quota;
2556 
2557     ir_ref_instruction(new_quota, ag->current_basic_block);
2558 
2559     return &instruction->base;
2560 }
2561 
ir_build_align_cast_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * align_bytes,Stage1ZirInst * target)2562 static Stage1ZirInst *ir_build_align_cast_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2563         Stage1ZirInst *align_bytes, Stage1ZirInst *target)
2564 {
2565     Stage1ZirInstAlignCast *instruction = ir_build_instruction<Stage1ZirInstAlignCast>(ag, scope, source_node);
2566     instruction->align_bytes = align_bytes;
2567     instruction->target = target;
2568 
2569     ir_ref_instruction(align_bytes, ag->current_basic_block);
2570     ir_ref_instruction(target, ag->current_basic_block);
2571 
2572     return &instruction->base;
2573 }
2574 
ir_build_resolve_result(Stage1AstGen * ag,Scope * scope,AstNode * source_node,ResultLoc * result_loc,Stage1ZirInst * ty)2575 static Stage1ZirInst *ir_build_resolve_result(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2576         ResultLoc *result_loc, Stage1ZirInst *ty)
2577 {
2578     Stage1ZirInstResolveResult *instruction = ir_build_instruction<Stage1ZirInstResolveResult>(ag, scope, source_node);
2579     instruction->result_loc = result_loc;
2580     instruction->ty = ty;
2581 
2582     if (ty != nullptr) ir_ref_instruction(ty, ag->current_basic_block);
2583 
2584     return &instruction->base;
2585 }
2586 
ir_build_reset_result(Stage1AstGen * ag,Scope * scope,AstNode * source_node,ResultLoc * result_loc)2587 static Stage1ZirInst *ir_build_reset_result(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2588         ResultLoc *result_loc)
2589 {
2590     Stage1ZirInstResetResult *instruction = ir_build_instruction<Stage1ZirInstResetResult>(ag, scope, source_node);
2591     instruction->result_loc = result_loc;
2592 
2593     return &instruction->base;
2594 }
2595 
ir_build_set_align_stack(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * align_bytes)2596 static Stage1ZirInst *ir_build_set_align_stack(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2597         Stage1ZirInst *align_bytes)
2598 {
2599     Stage1ZirInstSetAlignStack *instruction = ir_build_instruction<Stage1ZirInstSetAlignStack>(ag, scope, source_node);
2600     instruction->align_bytes = align_bytes;
2601 
2602     ir_ref_instruction(align_bytes, ag->current_basic_block);
2603 
2604     return &instruction->base;
2605 }
2606 
ir_build_arg_type(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * fn_type,Stage1ZirInst * arg_index,bool allow_var)2607 static Stage1ZirInst *ir_build_arg_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2608         Stage1ZirInst *fn_type, Stage1ZirInst *arg_index, bool allow_var)
2609 {
2610     Stage1ZirInstArgType *instruction = heap::c_allocator.create<Stage1ZirInstArgType>();
2611     instruction->base.id = allow_var ?
2612         Stage1ZirInstIdArgTypeAllowVarTrue : Stage1ZirInstIdArgTypeAllowVarFalse;
2613     instruction->base.scope = scope;
2614     instruction->base.source_node = source_node;
2615     instruction->base.debug_id = irb_next_debug_id(ag);
2616     instruction->base.owner_bb = ag->current_basic_block;
2617     ir_instruction_append(ag->current_basic_block, &instruction->base);
2618 
2619     instruction->fn_type = fn_type;
2620     instruction->arg_index = arg_index;
2621 
2622     ir_ref_instruction(fn_type, ag->current_basic_block);
2623     ir_ref_instruction(arg_index, ag->current_basic_block);
2624 
2625     return &instruction->base;
2626 }
2627 
ir_build_error_return_trace_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,IrInstErrorReturnTraceOptional optional)2628 static Stage1ZirInst *ir_build_error_return_trace_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2629         IrInstErrorReturnTraceOptional optional)
2630 {
2631     Stage1ZirInstErrorReturnTrace *inst = ir_build_instruction<Stage1ZirInstErrorReturnTrace>(ag, scope, source_node);
2632     inst->optional = optional;
2633 
2634     return &inst->base;
2635 }
2636 
ir_build_error_union(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * err_set,Stage1ZirInst * payload)2637 static Stage1ZirInst *ir_build_error_union(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2638         Stage1ZirInst *err_set, Stage1ZirInst *payload)
2639 {
2640     Stage1ZirInstErrorUnion *instruction = ir_build_instruction<Stage1ZirInstErrorUnion>(ag, scope, source_node);
2641     instruction->err_set = err_set;
2642     instruction->payload = payload;
2643 
2644     ir_ref_instruction(err_set, ag->current_basic_block);
2645     ir_ref_instruction(payload, ag->current_basic_block);
2646 
2647     return &instruction->base;
2648 }
2649 
ir_build_atomic_rmw_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * operand_type,Stage1ZirInst * ptr,Stage1ZirInst * op,Stage1ZirInst * operand,Stage1ZirInst * ordering)2650 static Stage1ZirInst *ir_build_atomic_rmw_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2651         Stage1ZirInst *operand_type, Stage1ZirInst *ptr, Stage1ZirInst *op, Stage1ZirInst *operand,
2652         Stage1ZirInst *ordering)
2653 {
2654     Stage1ZirInstAtomicRmw *instruction = ir_build_instruction<Stage1ZirInstAtomicRmw>(ag, scope, source_node);
2655     instruction->operand_type = operand_type;
2656     instruction->ptr = ptr;
2657     instruction->op = op;
2658     instruction->operand = operand;
2659     instruction->ordering = ordering;
2660 
2661     ir_ref_instruction(operand_type, ag->current_basic_block);
2662     ir_ref_instruction(ptr, ag->current_basic_block);
2663     ir_ref_instruction(op, ag->current_basic_block);
2664     ir_ref_instruction(operand, ag->current_basic_block);
2665     ir_ref_instruction(ordering, ag->current_basic_block);
2666 
2667     return &instruction->base;
2668 }
2669 
ir_build_atomic_load_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * operand_type,Stage1ZirInst * ptr,Stage1ZirInst * ordering)2670 static Stage1ZirInst *ir_build_atomic_load_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2671         Stage1ZirInst *operand_type, Stage1ZirInst *ptr, Stage1ZirInst *ordering)
2672 {
2673     Stage1ZirInstAtomicLoad *instruction = ir_build_instruction<Stage1ZirInstAtomicLoad>(ag, scope, source_node);
2674     instruction->operand_type = operand_type;
2675     instruction->ptr = ptr;
2676     instruction->ordering = ordering;
2677 
2678     ir_ref_instruction(operand_type, ag->current_basic_block);
2679     ir_ref_instruction(ptr, ag->current_basic_block);
2680     ir_ref_instruction(ordering, ag->current_basic_block);
2681 
2682     return &instruction->base;
2683 }
2684 
ir_build_atomic_store_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * operand_type,Stage1ZirInst * ptr,Stage1ZirInst * value,Stage1ZirInst * ordering)2685 static Stage1ZirInst *ir_build_atomic_store_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2686         Stage1ZirInst *operand_type, Stage1ZirInst *ptr, Stage1ZirInst *value, Stage1ZirInst *ordering)
2687 {
2688     Stage1ZirInstAtomicStore *instruction = ir_build_instruction<Stage1ZirInstAtomicStore>(ag, scope, source_node);
2689     instruction->operand_type = operand_type;
2690     instruction->ptr = ptr;
2691     instruction->value = value;
2692     instruction->ordering = ordering;
2693 
2694     ir_ref_instruction(operand_type, ag->current_basic_block);
2695     ir_ref_instruction(ptr, ag->current_basic_block);
2696     ir_ref_instruction(value, ag->current_basic_block);
2697     ir_ref_instruction(ordering, ag->current_basic_block);
2698 
2699     return &instruction->base;
2700 }
2701 
ir_build_save_err_ret_addr_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node)2702 static Stage1ZirInst *ir_build_save_err_ret_addr_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2703     Stage1ZirInstSaveErrRetAddr *inst = ir_build_instruction<Stage1ZirInstSaveErrRetAddr>(ag, scope, source_node);
2704     return &inst->base;
2705 }
2706 
ir_build_add_implicit_return_type(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * value,ResultLocReturn * result_loc_ret)2707 static Stage1ZirInst *ir_build_add_implicit_return_type(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2708         Stage1ZirInst *value, ResultLocReturn *result_loc_ret)
2709 {
2710     Stage1ZirInstAddImplicitReturnType *inst = ir_build_instruction<Stage1ZirInstAddImplicitReturnType>(ag, scope, source_node);
2711     inst->value = value;
2712     inst->result_loc_ret = result_loc_ret;
2713 
2714     ir_ref_instruction(value, ag->current_basic_block);
2715 
2716     return &inst->base;
2717 }
2718 
ir_build_has_decl(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * container,Stage1ZirInst * name)2719 static Stage1ZirInst *ir_build_has_decl(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2720         Stage1ZirInst *container, Stage1ZirInst *name)
2721 {
2722     Stage1ZirInstHasDecl *instruction = ir_build_instruction<Stage1ZirInstHasDecl>(ag, scope, source_node);
2723     instruction->container = container;
2724     instruction->name = name;
2725 
2726     ir_ref_instruction(container, ag->current_basic_block);
2727     ir_ref_instruction(name, ag->current_basic_block);
2728 
2729     return &instruction->base;
2730 }
2731 
ir_build_undeclared_identifier(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Buf * name)2732 static Stage1ZirInst *ir_build_undeclared_identifier(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Buf *name) {
2733     Stage1ZirInstUndeclaredIdent *instruction = ir_build_instruction<Stage1ZirInstUndeclaredIdent>(ag, scope, source_node);
2734     instruction->name = name;
2735 
2736     return &instruction->base;
2737 }
2738 
ir_build_check_runtime_scope(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * scope_is_comptime,Stage1ZirInst * is_comptime)2739 static Stage1ZirInst *ir_build_check_runtime_scope(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *scope_is_comptime, Stage1ZirInst *is_comptime) {
2740     Stage1ZirInstCheckRuntimeScope *instruction = ir_build_instruction<Stage1ZirInstCheckRuntimeScope>(ag, scope, source_node);
2741     instruction->scope_is_comptime = scope_is_comptime;
2742     instruction->is_comptime = is_comptime;
2743 
2744     ir_ref_instruction(scope_is_comptime, ag->current_basic_block);
2745     ir_ref_instruction(is_comptime, ag->current_basic_block);
2746 
2747     return &instruction->base;
2748 }
2749 
ir_build_union_init_named_field(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * union_type,Stage1ZirInst * field_name,Stage1ZirInst * field_result_loc,Stage1ZirInst * result_loc)2750 static Stage1ZirInst *ir_build_union_init_named_field(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2751     Stage1ZirInst *union_type, Stage1ZirInst *field_name, Stage1ZirInst *field_result_loc, Stage1ZirInst *result_loc)
2752 {
2753     Stage1ZirInstUnionInitNamedField *instruction = ir_build_instruction<Stage1ZirInstUnionInitNamedField>(ag, scope, source_node);
2754     instruction->union_type = union_type;
2755     instruction->field_name = field_name;
2756     instruction->field_result_loc = field_result_loc;
2757     instruction->result_loc = result_loc;
2758 
2759     ir_ref_instruction(union_type, ag->current_basic_block);
2760     ir_ref_instruction(field_name, ag->current_basic_block);
2761     ir_ref_instruction(field_result_loc, ag->current_basic_block);
2762     if (result_loc != nullptr) ir_ref_instruction(result_loc, ag->current_basic_block);
2763 
2764     return &instruction->base;
2765 }
2766 
ir_build_alloca_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * align,const char * name_hint,Stage1ZirInst * is_comptime)2767 static Stage1ZirInst *ir_build_alloca_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2768         Stage1ZirInst *align, const char *name_hint, Stage1ZirInst *is_comptime)
2769 {
2770     Stage1ZirInstAlloca *instruction = ir_build_instruction<Stage1ZirInstAlloca>(ag, scope, source_node);
2771     instruction->align = align;
2772     instruction->name_hint = name_hint;
2773     instruction->is_comptime = is_comptime;
2774 
2775     if (align != nullptr) ir_ref_instruction(align, ag->current_basic_block);
2776     if (is_comptime != nullptr) ir_ref_instruction(is_comptime, ag->current_basic_block);
2777 
2778     return &instruction->base;
2779 }
2780 
ir_build_end_expr(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * value,ResultLoc * result_loc)2781 static Stage1ZirInst *ir_build_end_expr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2782         Stage1ZirInst *value, ResultLoc *result_loc)
2783 {
2784     Stage1ZirInstEndExpr *instruction = ir_build_instruction<Stage1ZirInstEndExpr>(ag, scope, source_node);
2785     instruction->value = value;
2786     instruction->result_loc = result_loc;
2787 
2788     ir_ref_instruction(value, ag->current_basic_block);
2789 
2790     return &instruction->base;
2791 }
2792 
ir_build_suspend_begin_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node)2793 static Stage1ZirInstSuspendBegin *ir_build_suspend_begin_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2794     return ir_build_instruction<Stage1ZirInstSuspendBegin>(ag, scope, source_node);
2795 }
2796 
ir_build_suspend_finish_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInstSuspendBegin * begin)2797 static Stage1ZirInst *ir_build_suspend_finish_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2798         Stage1ZirInstSuspendBegin *begin)
2799 {
2800     Stage1ZirInstSuspendFinish *inst = ir_build_instruction<Stage1ZirInstSuspendFinish>(ag, scope, source_node);
2801     inst->begin = begin;
2802 
2803     ir_ref_instruction(&begin->base, ag->current_basic_block);
2804 
2805     return &inst->base;
2806 }
2807 
ir_build_await_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * frame,ResultLoc * result_loc,bool is_nosuspend)2808 static Stage1ZirInst *ir_build_await_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2809         Stage1ZirInst *frame, ResultLoc *result_loc, bool is_nosuspend)
2810 {
2811     Stage1ZirInstAwait *instruction = ir_build_instruction<Stage1ZirInstAwait>(ag, scope, source_node);
2812     instruction->frame = frame;
2813     instruction->result_loc = result_loc;
2814     instruction->is_nosuspend = is_nosuspend;
2815 
2816     ir_ref_instruction(frame, ag->current_basic_block);
2817 
2818     return &instruction->base;
2819 }
2820 
ir_build_resume_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * frame)2821 static Stage1ZirInst *ir_build_resume_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *frame) {
2822     Stage1ZirInstResume *instruction = ir_build_instruction<Stage1ZirInstResume>(ag, scope, source_node);
2823     instruction->frame = frame;
2824 
2825     ir_ref_instruction(frame, ag->current_basic_block);
2826 
2827     return &instruction->base;
2828 }
2829 
ir_build_spill_begin_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * operand,SpillId spill_id)2830 static Stage1ZirInstSpillBegin *ir_build_spill_begin_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2831         Stage1ZirInst *operand, SpillId spill_id)
2832 {
2833     Stage1ZirInstSpillBegin *instruction = ir_build_instruction<Stage1ZirInstSpillBegin>(ag, scope, source_node);
2834     instruction->operand = operand;
2835     instruction->spill_id = spill_id;
2836 
2837     ir_ref_instruction(operand, ag->current_basic_block);
2838 
2839     return instruction;
2840 }
2841 
ir_build_spill_end_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInstSpillBegin * begin)2842 static Stage1ZirInst *ir_build_spill_end_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2843         Stage1ZirInstSpillBegin *begin)
2844 {
2845     Stage1ZirInstSpillEnd *instruction = ir_build_instruction<Stage1ZirInstSpillEnd>(ag, scope, source_node);
2846     instruction->begin = begin;
2847 
2848     ir_ref_instruction(&begin->base, ag->current_basic_block);
2849 
2850     return &instruction->base;
2851 }
2852 
ir_build_wasm_memory_size_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * index)2853 static Stage1ZirInst *ir_build_wasm_memory_size_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *index) {
2854     Stage1ZirInstWasmMemorySize *instruction = ir_build_instruction<Stage1ZirInstWasmMemorySize>(ag, scope, source_node);
2855     instruction->index = index;
2856 
2857     ir_ref_instruction(index, ag->current_basic_block);
2858 
2859     return &instruction->base;
2860 }
2861 
ir_build_wasm_memory_grow_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * index,Stage1ZirInst * delta)2862 static Stage1ZirInst *ir_build_wasm_memory_grow_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node, Stage1ZirInst *index, Stage1ZirInst *delta) {
2863     Stage1ZirInstWasmMemoryGrow *instruction = ir_build_instruction<Stage1ZirInstWasmMemoryGrow>(ag, scope, source_node);
2864     instruction->index = index;
2865     instruction->delta = delta;
2866 
2867     ir_ref_instruction(index, ag->current_basic_block);
2868     ir_ref_instruction(delta, ag->current_basic_block);
2869 
2870     return &instruction->base;
2871 }
2872 
ir_build_src(Stage1AstGen * ag,Scope * scope,AstNode * source_node)2873 static Stage1ZirInst *ir_build_src(Stage1AstGen *ag, Scope *scope, AstNode *source_node) {
2874     Stage1ZirInstSrc *instruction = ir_build_instruction<Stage1ZirInstSrc>(ag, scope, source_node);
2875 
2876     return &instruction->base;
2877 }
2878 
ir_build_prefetch(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * ptr,Stage1ZirInst * options)2879 static Stage1ZirInst *ir_build_prefetch(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
2880         Stage1ZirInst *ptr, Stage1ZirInst *options)
2881 {
2882     Stage1ZirInstPrefetch *prefetch_instruction = ir_build_instruction<Stage1ZirInstPrefetch>(
2883             ag, scope, source_node);
2884     prefetch_instruction->ptr = ptr;
2885     prefetch_instruction->options = options;
2886 
2887     ir_ref_instruction(ptr, ag->current_basic_block);
2888     ir_ref_instruction(options, ag->current_basic_block);
2889 
2890     return &prefetch_instruction->base;
2891 }
2892 
2893 
ir_count_defers(Stage1AstGen * ag,Scope * inner_scope,Scope * outer_scope,size_t * results)2894 static void ir_count_defers(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_scope, size_t *results) {
2895     results[ReturnKindUnconditional] = 0;
2896     results[ReturnKindError] = 0;
2897 
2898     Scope *scope = inner_scope;
2899 
2900     while (scope != outer_scope) {
2901         assert(scope);
2902         switch (scope->id) {
2903             case ScopeIdDefer: {
2904                 AstNode *defer_node = scope->source_node;
2905                 assert(defer_node->type == NodeTypeDefer);
2906                 ReturnKind defer_kind = defer_node->data.defer.kind;
2907                 results[defer_kind] += 1;
2908                 scope = scope->parent;
2909                 continue;
2910             }
2911             case ScopeIdDecls:
2912             case ScopeIdFnDef:
2913                 return;
2914             case ScopeIdBlock:
2915             case ScopeIdVarDecl:
2916             case ScopeIdLoop:
2917             case ScopeIdSuspend:
2918             case ScopeIdCompTime:
2919             case ScopeIdNoSuspend:
2920             case ScopeIdRuntime:
2921             case ScopeIdTypeOf:
2922             case ScopeIdExpr:
2923                 scope = scope->parent;
2924                 continue;
2925             case ScopeIdDeferExpr:
2926             case ScopeIdCImport:
2927                 zig_unreachable();
2928         }
2929     }
2930 }
2931 
astgen_defers_for_block(Stage1AstGen * ag,Scope * inner_scope,Scope * outer_scope,bool * is_noreturn,Stage1ZirInst * err_value)2932 static bool astgen_defers_for_block(Stage1AstGen *ag, Scope *inner_scope, Scope *outer_scope, bool *is_noreturn, Stage1ZirInst *err_value) {
2933     Scope *scope = inner_scope;
2934     if (is_noreturn != nullptr) *is_noreturn = false;
2935     while (scope != outer_scope) {
2936         if (!scope)
2937             return true;
2938 
2939         switch (scope->id) {
2940             case ScopeIdDefer: {
2941                 AstNode *defer_node = scope->source_node;
2942                 assert(defer_node->type == NodeTypeDefer);
2943                 ReturnKind defer_kind = defer_node->data.defer.kind;
2944                 AstNode *defer_expr_node = defer_node->data.defer.expr;
2945                 AstNode *defer_var_node = defer_node->data.defer.err_payload;
2946 
2947                 if (defer_kind == ReturnKindError && err_value == nullptr) {
2948                     // This is an `errdefer` but we're generating code for a
2949                     // `return` that doesn't return an error, skip it
2950                     scope = scope->parent;
2951                     continue;
2952                 }
2953 
2954                 Scope *defer_expr_scope = defer_node->data.defer.expr_scope;
2955                 if (defer_var_node != nullptr) {
2956                     assert(defer_kind == ReturnKindError);
2957                     assert(defer_var_node->type == NodeTypeIdentifier);
2958                     Buf *var_name = node_identifier_buf(defer_var_node);
2959 
2960                     if (defer_expr_node->type == NodeTypeUnreachable) {
2961                         add_node_error(ag->codegen, defer_var_node,
2962                             buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));
2963                         return false;
2964                     }
2965 
2966                     Stage1ZirInst *is_comptime;
2967                     if (ir_should_inline(ag->exec, defer_expr_scope)) {
2968                         is_comptime = ir_build_const_bool(ag, defer_expr_scope,
2969                             defer_expr_node, true);
2970                     } else {
2971                         is_comptime = ir_build_test_comptime(ag, defer_expr_scope,
2972                             defer_expr_node, err_value);
2973                     }
2974 
2975                     ZigVar *err_var = ir_create_var(ag, defer_var_node, defer_expr_scope,
2976                         var_name, true, true, false, is_comptime);
2977                     build_decl_var_and_init(ag, defer_expr_scope, defer_var_node, err_var, err_value,
2978                         buf_ptr(var_name), is_comptime);
2979 
2980                     defer_expr_scope = err_var->child_scope;
2981                 }
2982 
2983                 Stage1ZirInst *defer_expr_value = astgen_node(ag, defer_expr_node, defer_expr_scope);
2984                 if (defer_expr_value == ag->codegen->invalid_inst_src)
2985                     return ag->codegen->invalid_inst_src;
2986 
2987                 if (instr_is_unreachable(defer_expr_value)) {
2988                     if (is_noreturn != nullptr) *is_noreturn = true;
2989                 } else {
2990                     ir_build_check_statement_is_void(ag, defer_expr_scope, defer_expr_node,
2991                                 defer_expr_value);
2992                 }
2993                 scope = scope->parent;
2994                 continue;
2995             }
2996             case ScopeIdDecls:
2997             case ScopeIdFnDef:
2998                 return true;
2999             case ScopeIdBlock:
3000             case ScopeIdVarDecl:
3001             case ScopeIdLoop:
3002             case ScopeIdSuspend:
3003             case ScopeIdCompTime:
3004             case ScopeIdNoSuspend:
3005             case ScopeIdRuntime:
3006             case ScopeIdTypeOf:
3007             case ScopeIdExpr:
3008                 scope = scope->parent;
3009                 continue;
3010             case ScopeIdDeferExpr:
3011             case ScopeIdCImport:
3012                 zig_unreachable();
3013         }
3014     }
3015     return true;
3016 }
3017 
ir_set_cursor_at_end(Stage1AstGen * ag,Stage1ZirBasicBlock * basic_block)3018 static void ir_set_cursor_at_end(Stage1AstGen *ag, Stage1ZirBasicBlock *basic_block) {
3019     assert(basic_block);
3020     ag->current_basic_block = basic_block;
3021 }
3022 
ir_set_cursor_at_end_and_append_block(Stage1AstGen * ag,Stage1ZirBasicBlock * basic_block)3023 static void ir_set_cursor_at_end_and_append_block(Stage1AstGen *ag, Stage1ZirBasicBlock *basic_block) {
3024     basic_block->index = ag->exec->basic_block_list.length;
3025     ag->exec->basic_block_list.append(basic_block);
3026     ir_set_cursor_at_end(ag, basic_block);
3027 }
3028 
get_scope_suspend(Scope * scope)3029 static ScopeSuspend *get_scope_suspend(Scope *scope) {
3030     while (scope) {
3031         if (scope->id == ScopeIdSuspend)
3032             return (ScopeSuspend *)scope;
3033         if (scope->id == ScopeIdFnDef)
3034             return nullptr;
3035 
3036         scope = scope->parent;
3037     }
3038     return nullptr;
3039 }
3040 
get_scope_defer_expr(Scope * scope)3041 static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) {
3042     while (scope) {
3043         if (scope->id == ScopeIdDeferExpr)
3044             return (ScopeDeferExpr *)scope;
3045         if (scope->id == ScopeIdFnDef)
3046             return nullptr;
3047 
3048         scope = scope->parent;
3049     }
3050     return nullptr;
3051 }
3052 
astgen_return(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)3053 static Stage1ZirInst *astgen_return(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
3054     assert(node->type == NodeTypeReturnExpr);
3055 
3056     ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope);
3057     if (scope_defer_expr) {
3058         if (!scope_defer_expr->reported_err) {
3059             add_node_error(ag->codegen, node, buf_sprintf("cannot return from defer expression"));
3060             scope_defer_expr->reported_err = true;
3061         }
3062         return ag->codegen->invalid_inst_src;
3063     }
3064 
3065     Scope *outer_scope = ag->exec->begin_scope;
3066 
3067     AstNode *expr_node = node->data.return_expr.expr;
3068     switch (node->data.return_expr.kind) {
3069         case ReturnKindUnconditional:
3070             {
3071                 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
3072                 result_loc_ret->base.id = ResultLocIdReturn;
3073                 ir_build_reset_result(ag, scope, node, &result_loc_ret->base);
3074 
3075                 Stage1ZirInst *return_value;
3076                 if (expr_node) {
3077                     // Temporarily set this so that if we return a type it gets the name of the function
3078                     ZigFn *prev_name_fn = ag->exec->name_fn;
3079                     ag->exec->name_fn = ag->fn;
3080                     return_value = astgen_node_extra(ag, expr_node, scope, LValNone, &result_loc_ret->base);
3081                     ag->exec->name_fn = prev_name_fn;
3082                     if (return_value == ag->codegen->invalid_inst_src)
3083                         return ag->codegen->invalid_inst_src;
3084                 } else {
3085                     return_value = ir_build_const_void(ag, scope, node);
3086                     ir_build_end_expr(ag, scope, node, return_value, &result_loc_ret->base);
3087                 }
3088 
3089                 ir_build_add_implicit_return_type(ag, scope, node, return_value, result_loc_ret);
3090 
3091                 size_t defer_counts[2];
3092                 ir_count_defers(ag, scope, outer_scope, defer_counts);
3093                 bool have_err_defers = defer_counts[ReturnKindError] > 0;
3094                 if (!have_err_defers && !ag->codegen->have_err_ret_tracing) {
3095                     // only generate unconditional defers
3096                     if (!astgen_defers_for_block(ag, scope, outer_scope, nullptr, nullptr))
3097                         return ag->codegen->invalid_inst_src;
3098                     Stage1ZirInst *result = ir_build_return_src(ag, scope, node, nullptr);
3099                     result_loc_ret->base.source_instruction = result;
3100                     return result;
3101                 }
3102                 bool should_inline = ir_should_inline(ag->exec, scope);
3103 
3104                 Stage1ZirBasicBlock *err_block = ir_create_basic_block(ag, scope, "ErrRetErr");
3105                 Stage1ZirBasicBlock *ok_block = ir_create_basic_block(ag, scope, "ErrRetOk");
3106 
3107                 Stage1ZirInst *is_err = ir_build_test_err_src(ag, scope, node, return_value, false, true);
3108 
3109                 Stage1ZirInst *is_comptime;
3110                 if (should_inline) {
3111                     is_comptime = ir_build_const_bool(ag, scope, node, should_inline);
3112                 } else {
3113                     is_comptime = ir_build_test_comptime(ag, scope, node, is_err);
3114                 }
3115 
3116                 ir_build_cond_br(ag, scope, node, is_err, err_block, ok_block, is_comptime);
3117                 Stage1ZirBasicBlock *ret_stmt_block = ir_create_basic_block(ag, scope, "RetStmt");
3118 
3119                 ir_set_cursor_at_end_and_append_block(ag, err_block);
3120                 if (!astgen_defers_for_block(ag, scope, outer_scope, nullptr, return_value))
3121                     return ag->codegen->invalid_inst_src;
3122                 if (ag->codegen->have_err_ret_tracing && !should_inline) {
3123                     ir_build_save_err_ret_addr_src(ag, scope, node);
3124                 }
3125                 ir_build_br(ag, scope, node, ret_stmt_block, is_comptime);
3126 
3127                 ir_set_cursor_at_end_and_append_block(ag, ok_block);
3128                 if (!astgen_defers_for_block(ag, scope, outer_scope, nullptr, nullptr))
3129                     return ag->codegen->invalid_inst_src;
3130                 ir_build_br(ag, scope, node, ret_stmt_block, is_comptime);
3131 
3132                 ir_set_cursor_at_end_and_append_block(ag, ret_stmt_block);
3133                 Stage1ZirInst *result = ir_build_return_src(ag, scope, node, nullptr);
3134                 result_loc_ret->base.source_instruction = result;
3135                 return result;
3136             }
3137         case ReturnKindError:
3138             {
3139                 assert(expr_node);
3140                 Stage1ZirInst *err_union_ptr = astgen_node_extra(ag, expr_node, scope, LValPtr, nullptr);
3141                 if (err_union_ptr == ag->codegen->invalid_inst_src)
3142                     return ag->codegen->invalid_inst_src;
3143                 Stage1ZirInst *is_err_val = ir_build_test_err_src(ag, scope, node, err_union_ptr, true, false);
3144 
3145                 Stage1ZirBasicBlock *return_block = ir_create_basic_block(ag, scope, "ErrRetReturn");
3146                 Stage1ZirBasicBlock *continue_block = ir_create_basic_block(ag, scope, "ErrRetContinue");
3147                 Stage1ZirInst *is_comptime;
3148                 bool should_inline = ir_should_inline(ag->exec, scope);
3149                 if (should_inline) {
3150                     is_comptime = ir_build_const_bool(ag, scope, node, true);
3151                 } else {
3152                     is_comptime = ir_build_test_comptime(ag, scope, node, is_err_val);
3153                 }
3154                 ir_build_cond_br(ag, scope, node, is_err_val, return_block, continue_block, is_comptime);
3155 
3156                 ir_set_cursor_at_end_and_append_block(ag, return_block);
3157                 Stage1ZirInst *err_val_ptr = ir_build_unwrap_err_code_src(ag, scope, node, err_union_ptr);
3158                 Stage1ZirInst *err_val = ir_build_load_ptr(ag, scope, node, err_val_ptr);
3159                 ir_build_add_implicit_return_type(ag, scope, node, err_val, nullptr);
3160                 Stage1ZirInstSpillBegin *spill_begin = ir_build_spill_begin_src(ag, scope, node, err_val,
3161                         SpillIdRetErrCode);
3162                 ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
3163                 result_loc_ret->base.id = ResultLocIdReturn;
3164                 ir_build_reset_result(ag, scope, node, &result_loc_ret->base);
3165                 ir_build_end_expr(ag, scope, node, err_val, &result_loc_ret->base);
3166 
3167                 bool is_noreturn = false;
3168                 if (!astgen_defers_for_block(ag, scope, outer_scope, &is_noreturn, err_val)) {
3169                     return ag->codegen->invalid_inst_src;
3170                 }
3171                 if (!is_noreturn) {
3172                     if (ag->codegen->have_err_ret_tracing && !should_inline) {
3173                         ir_build_save_err_ret_addr_src(ag, scope, node);
3174                     }
3175                     err_val = ir_build_spill_end_src(ag, scope, node, spill_begin);
3176                     Stage1ZirInst *ret_inst = ir_build_return_src(ag, scope, node, err_val);
3177                     result_loc_ret->base.source_instruction = ret_inst;
3178                 }
3179 
3180                 ir_set_cursor_at_end_and_append_block(ag, continue_block);
3181                 Stage1ZirInst *unwrapped_ptr = ir_build_unwrap_err_payload_src(ag, scope, node, err_union_ptr, false, false);
3182                 if (lval == LValPtr)
3183                     return unwrapped_ptr;
3184                 else
3185                     return ir_expr_wrap(ag, scope, ir_build_load_ptr(ag, scope, node, unwrapped_ptr), result_loc);
3186             }
3187     }
3188     zig_unreachable();
3189 }
3190 
create_local_var(CodeGen * codegen,AstNode * node,Scope * parent_scope,Buf * name,bool src_is_const,bool gen_is_const,bool is_shadowable,Stage1ZirInst * is_comptime,bool skip_name_check)3191 ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope,
3192         Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, Stage1ZirInst *is_comptime,
3193         bool skip_name_check)
3194 {
3195     ZigVar *variable_entry = heap::c_allocator.create<ZigVar>();
3196     variable_entry->parent_scope = parent_scope;
3197     variable_entry->shadowable = is_shadowable;
3198     variable_entry->is_comptime = is_comptime;
3199     variable_entry->src_arg_index = SIZE_MAX;
3200     variable_entry->const_value = codegen->pass1_arena->create<ZigValue>();
3201 
3202     if (is_comptime != nullptr) {
3203         is_comptime->ref_count += 1;
3204     }
3205 
3206     if (name) {
3207         variable_entry->name = strdup(buf_ptr(name));
3208 
3209         if (!skip_name_check) {
3210             ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr);
3211             if (existing_var && !existing_var->shadowable) {
3212                 if (existing_var->var_type == nullptr || !type_is_invalid(existing_var->var_type)) {
3213                     ErrorMsg *msg = add_node_error(codegen, node,
3214                             buf_sprintf("redeclaration of variable '%s'", buf_ptr(name)));
3215                     add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration here"));
3216                 }
3217                 variable_entry->var_type = codegen->builtin_types.entry_invalid;
3218             }
3219         }
3220     } else {
3221         assert(is_shadowable);
3222         // TODO make this name not actually be in scope. user should be able to make a variable called "_anon"
3223         // might already be solved, let's just make sure it has test coverage
3224         // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables
3225         variable_entry->name = "_anon";
3226     }
3227 
3228     variable_entry->src_is_const = src_is_const;
3229     variable_entry->gen_is_const = gen_is_const;
3230     variable_entry->decl_node = node;
3231     variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry);
3232 
3233     return variable_entry;
3234 }
3235 
3236 
3237 // Set name to nullptr to make the variable anonymous (not visible to programmer).
3238 // After you call this function var->child_scope has the variable in scope
ir_create_var(Stage1AstGen * ag,AstNode * node,Scope * scope,Buf * name,bool src_is_const,bool gen_is_const,bool is_shadowable,Stage1ZirInst * is_comptime)3239 static ZigVar *ir_create_var(Stage1AstGen *ag, AstNode *node, Scope *scope, Buf *name,
3240         bool src_is_const, bool gen_is_const, bool is_shadowable, Stage1ZirInst *is_comptime)
3241 {
3242     bool is_underscored = name ? buf_eql_str(name, "_") : false;
3243     ZigVar *var = create_local_var(ag->codegen, node, scope,
3244             (is_underscored ? nullptr : name), src_is_const, gen_is_const,
3245             (is_underscored ? true : is_shadowable), is_comptime, false);
3246     assert(var->child_scope);
3247     return var;
3248 }
3249 
create_peer_result(ResultLocPeerParent * peer_parent)3250 static ResultLocPeer *create_peer_result(ResultLocPeerParent *peer_parent) {
3251     ResultLocPeer *result = heap::c_allocator.create<ResultLocPeer>();
3252     result->base.id = ResultLocIdPeer;
3253     result->base.source_instruction = peer_parent->base.source_instruction;
3254     result->parent = peer_parent;
3255     result->base.allow_write_through_const = peer_parent->parent->allow_write_through_const;
3256     return result;
3257 }
3258 
is_duplicate_label(CodeGen * g,Scope * scope,AstNode * node,Buf * name)3259 static bool is_duplicate_label(CodeGen *g, Scope *scope, AstNode *node, Buf *name) {
3260     if (name == nullptr) return false;
3261 
3262     for (;;) {
3263         if (scope == nullptr || scope->id == ScopeIdFnDef) {
3264             break;
3265         } else if (scope->id == ScopeIdBlock || scope->id == ScopeIdLoop) {
3266             Buf *this_block_name = scope->id == ScopeIdBlock ? ((ScopeBlock *)scope)->name : ((ScopeLoop *)scope)->name;
3267             if (this_block_name != nullptr && buf_eql_buf(name, this_block_name)) {
3268                 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("redeclaration of label '%s'", buf_ptr(name)));
3269                 add_error_note(g, msg, scope->source_node, buf_sprintf("previous declaration here"));
3270                 return true;
3271             }
3272         }
3273         scope = scope->parent;
3274     }
3275     return false;
3276 }
3277 
astgen_block(Stage1AstGen * ag,Scope * parent_scope,AstNode * block_node,LVal lval,ResultLoc * result_loc)3278 static Stage1ZirInst *astgen_block(Stage1AstGen *ag, Scope *parent_scope, AstNode *block_node, LVal lval,
3279         ResultLoc *result_loc)
3280 {
3281     assert(block_node->type == NodeTypeBlock);
3282 
3283     ZigList<Stage1ZirInst *> incoming_values = {0};
3284     ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
3285 
3286     if (is_duplicate_label(ag->codegen, parent_scope, block_node, block_node->data.block.name))
3287         return ag->codegen->invalid_inst_src;
3288 
3289     ScopeBlock *scope_block = create_block_scope(ag->codegen, block_node, parent_scope);
3290 
3291     Scope *outer_block_scope = &scope_block->base;
3292     Scope *child_scope = outer_block_scope;
3293 
3294     ZigFn *fn_entry = scope_fn_entry(parent_scope);
3295     if (fn_entry && fn_entry->child_scope == parent_scope) {
3296         fn_entry->def_scope = scope_block;
3297     }
3298 
3299     if (block_node->data.block.statements.length == 0) {
3300         if (scope_block->name != nullptr) {
3301             add_node_error(ag->codegen, block_node, buf_sprintf("unused block label"));
3302         }
3303         // {}
3304         return ir_lval_wrap(ag, parent_scope, ir_build_const_void(ag, child_scope, block_node), lval, result_loc);
3305     }
3306 
3307     if (block_node->data.block.name != nullptr) {
3308         scope_block->lval = lval;
3309         scope_block->incoming_blocks = &incoming_blocks;
3310         scope_block->incoming_values = &incoming_values;
3311         scope_block->end_block = ir_create_basic_block(ag, parent_scope, "BlockEnd");
3312         scope_block->is_comptime = ir_build_const_bool(ag, parent_scope, block_node,
3313                 ir_should_inline(ag->exec, parent_scope));
3314 
3315         scope_block->peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
3316         scope_block->peer_parent->base.id = ResultLocIdPeerParent;
3317         scope_block->peer_parent->base.source_instruction = scope_block->is_comptime;
3318         scope_block->peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const;
3319         scope_block->peer_parent->end_bb = scope_block->end_block;
3320         scope_block->peer_parent->is_comptime = scope_block->is_comptime;
3321         scope_block->peer_parent->parent = result_loc;
3322         ir_build_reset_result(ag, parent_scope, block_node, &scope_block->peer_parent->base);
3323     }
3324 
3325     bool is_continuation_unreachable = false;
3326     bool found_invalid_inst = false;
3327     Stage1ZirInst *noreturn_return_value = nullptr;
3328     for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) {
3329         AstNode *statement_node = block_node->data.block.statements.at(i);
3330 
3331         Stage1ZirInst *statement_value = astgen_node(ag, statement_node, child_scope);
3332         if (statement_value == ag->codegen->invalid_inst_src) {
3333             // keep generating all the elements of the block in case of error,
3334             // we want to collect other compile errors
3335             found_invalid_inst = true;
3336             continue;
3337         }
3338 
3339         is_continuation_unreachable = instr_is_unreachable(statement_value);
3340         if (is_continuation_unreachable) {
3341             // keep the last noreturn statement value around in case we need to return it
3342             noreturn_return_value = statement_value;
3343         }
3344         // This logic must be kept in sync with
3345         // [STMT_EXPR_TEST_THING] <--- (search this token)
3346         if (statement_node->type == NodeTypeDefer) {
3347             // defer starts a new scope
3348             child_scope = statement_node->data.defer.child_scope;
3349             assert(child_scope);
3350         } else if (statement_value->id == Stage1ZirInstIdDeclVar) {
3351             // variable declarations start a new scope
3352             Stage1ZirInstDeclVar *decl_var_instruction = (Stage1ZirInstDeclVar *)statement_value;
3353             child_scope = decl_var_instruction->var->child_scope;
3354         } else if (!is_continuation_unreachable) {
3355             // this statement's value must be void
3356             ir_build_check_statement_is_void(ag, child_scope, statement_node, statement_value);
3357         }
3358     }
3359 
3360     if (scope_block->name != nullptr && scope_block->name_used == false) {
3361         add_node_error(ag->codegen, block_node, buf_sprintf("unused block label"));
3362     }
3363 
3364     if (found_invalid_inst)
3365         return ag->codegen->invalid_inst_src;
3366 
3367     if (is_continuation_unreachable) {
3368         assert(noreturn_return_value != nullptr);
3369         if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) {
3370             return noreturn_return_value;
3371         }
3372 
3373         if (scope_block->peer_parent != nullptr && scope_block->peer_parent->peers.length != 0) {
3374             scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block;
3375         }
3376         ir_set_cursor_at_end_and_append_block(ag, scope_block->end_block);
3377         Stage1ZirInst *phi = ir_build_phi(ag, parent_scope, block_node, incoming_blocks.length,
3378                 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);
3379         return ir_expr_wrap(ag, parent_scope, phi, result_loc);
3380     } else {
3381         incoming_blocks.append(ag->current_basic_block);
3382         Stage1ZirInst *else_expr_result = ir_build_const_void(ag, parent_scope, block_node);
3383 
3384         if (scope_block->peer_parent != nullptr) {
3385             ResultLocPeer *peer_result = create_peer_result(scope_block->peer_parent);
3386             scope_block->peer_parent->peers.append(peer_result);
3387             ir_build_end_expr(ag, parent_scope, block_node, else_expr_result, &peer_result->base);
3388 
3389             if (scope_block->peer_parent->peers.length != 0) {
3390                 scope_block->peer_parent->peers.last()->next_bb = scope_block->end_block;
3391             }
3392         }
3393 
3394         incoming_values.append(else_expr_result);
3395     }
3396 
3397     bool is_return_from_fn = block_node == ag->main_block_node;
3398     if (!is_return_from_fn) {
3399         if (!astgen_defers_for_block(ag, child_scope, outer_block_scope, nullptr, nullptr))
3400             return ag->codegen->invalid_inst_src;
3401     }
3402 
3403     Stage1ZirInst *result;
3404     if (block_node->data.block.name != nullptr) {
3405         ir_build_br(ag, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime);
3406         ir_set_cursor_at_end_and_append_block(ag, scope_block->end_block);
3407         Stage1ZirInst *phi = ir_build_phi(ag, parent_scope, block_node, incoming_blocks.length,
3408                 incoming_blocks.items, incoming_values.items, scope_block->peer_parent);
3409         result = ir_expr_wrap(ag, parent_scope, phi, result_loc);
3410     } else {
3411         Stage1ZirInst *void_inst = ir_build_const_void(ag, child_scope, block_node);
3412         result = ir_lval_wrap(ag, parent_scope, void_inst, lval, result_loc);
3413     }
3414     if (!is_return_from_fn)
3415         return result;
3416 
3417     // no need for save_err_ret_addr because this cannot return error
3418     // only generate unconditional defers
3419 
3420     ir_build_add_implicit_return_type(ag, child_scope, block_node, result, nullptr);
3421     ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
3422     result_loc_ret->base.id = ResultLocIdReturn;
3423     ir_build_reset_result(ag, parent_scope, block_node, &result_loc_ret->base);
3424     ir_build_end_expr(ag, parent_scope, block_node, result, &result_loc_ret->base);
3425     if (!astgen_defers_for_block(ag, child_scope, outer_block_scope, nullptr, nullptr))
3426         return ag->codegen->invalid_inst_src;
3427     return ir_build_return_src(ag, child_scope, result->source_node, result);
3428 }
3429 
astgen_bin_op_id(Stage1AstGen * ag,Scope * scope,AstNode * node,IrBinOp op_id)3430 static Stage1ZirInst *astgen_bin_op_id(Stage1AstGen *ag, Scope *scope, AstNode *node, IrBinOp op_id) {
3431     Scope *inner_scope = scope;
3432     if (op_id == IrBinOpArrayCat || op_id == IrBinOpArrayMult) {
3433         inner_scope = create_comptime_scope(ag->codegen, node, scope);
3434     }
3435 
3436     Stage1ZirInst *op1 = astgen_node(ag, node->data.bin_op_expr.op1, inner_scope);
3437     Stage1ZirInst *op2 = astgen_node(ag, node->data.bin_op_expr.op2, inner_scope);
3438 
3439     if (op1 == ag->codegen->invalid_inst_src || op2 == ag->codegen->invalid_inst_src)
3440         return ag->codegen->invalid_inst_src;
3441 
3442     return ir_build_bin_op(ag, scope, node, op_id, op1, op2, true);
3443 }
3444 
astgen_merge_err_sets(Stage1AstGen * ag,Scope * scope,AstNode * node)3445 static Stage1ZirInst *astgen_merge_err_sets(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3446     Stage1ZirInst *op1 = astgen_node(ag, node->data.bin_op_expr.op1, scope);
3447     Stage1ZirInst *op2 = astgen_node(ag, node->data.bin_op_expr.op2, scope);
3448 
3449     if (op1 == ag->codegen->invalid_inst_src || op2 == ag->codegen->invalid_inst_src)
3450         return ag->codegen->invalid_inst_src;
3451 
3452     // TODO only pass type_name when the || operator is the top level AST node in the var decl expr
3453     Buf bare_name = BUF_INIT;
3454     Buf *type_name = get_anon_type_name(ag->codegen, ag->exec, "error", scope, node, &bare_name, nullptr);
3455 
3456     return ir_build_merge_err_sets(ag, scope, node, op1, op2, type_name);
3457 }
3458 
astgen_assign(Stage1AstGen * ag,Scope * scope,AstNode * node)3459 static Stage1ZirInst *astgen_assign(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3460     Stage1ZirInst *lvalue = astgen_node_extra(ag, node->data.bin_op_expr.op1, scope, LValAssign, nullptr);
3461     if (lvalue == ag->codegen->invalid_inst_src)
3462         return ag->codegen->invalid_inst_src;
3463 
3464     ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
3465     result_loc_inst->base.id = ResultLocIdInstruction;
3466     result_loc_inst->base.source_instruction = lvalue;
3467     ir_ref_instruction(lvalue, ag->current_basic_block);
3468     ir_build_reset_result(ag, scope, node, &result_loc_inst->base);
3469 
3470     Stage1ZirInst *rvalue = astgen_node_extra(ag, node->data.bin_op_expr.op2, scope, LValNone,
3471             &result_loc_inst->base);
3472     if (rvalue == ag->codegen->invalid_inst_src)
3473         return ag->codegen->invalid_inst_src;
3474 
3475     return ir_build_const_void(ag, scope, node);
3476 }
3477 
astgen_assign_op(Stage1AstGen * ag,Scope * scope,AstNode * node,IrBinOp op_id)3478 static Stage1ZirInst *astgen_assign_op(Stage1AstGen *ag, Scope *scope, AstNode *node, IrBinOp op_id) {
3479     Stage1ZirInst *lvalue = astgen_node_extra(ag, node->data.bin_op_expr.op1, scope, LValAssign, nullptr);
3480     if (lvalue == ag->codegen->invalid_inst_src)
3481         return lvalue;
3482     Stage1ZirInst *op1 = ir_build_load_ptr(ag, scope, node->data.bin_op_expr.op1, lvalue);
3483     Stage1ZirInst *op2 = astgen_node(ag, node->data.bin_op_expr.op2, scope);
3484     if (op2 == ag->codegen->invalid_inst_src)
3485         return op2;
3486     Stage1ZirInst *result = ir_build_bin_op(ag, scope, node, op_id, op1, op2, true);
3487     ir_build_store_ptr(ag, scope, node, lvalue, result);
3488     return ir_build_const_void(ag, scope, node);
3489 }
3490 
astgen_bool_or(Stage1AstGen * ag,Scope * scope,AstNode * node)3491 static Stage1ZirInst *astgen_bool_or(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3492     assert(node->type == NodeTypeBinOpExpr);
3493 
3494     Stage1ZirInst *val1 = astgen_node(ag, node->data.bin_op_expr.op1, scope);
3495     if (val1 == ag->codegen->invalid_inst_src)
3496         return ag->codegen->invalid_inst_src;
3497     Stage1ZirBasicBlock *post_val1_block = ag->current_basic_block;
3498 
3499     Stage1ZirInst *is_comptime;
3500     if (ir_should_inline(ag->exec, scope)) {
3501         is_comptime = ir_build_const_bool(ag, scope, node, true);
3502     } else {
3503         is_comptime = ir_build_test_comptime(ag, scope, node, val1);
3504     }
3505 
3506     // block for when val1 == false
3507     Stage1ZirBasicBlock *false_block = ir_create_basic_block(ag, scope, "BoolOrFalse");
3508     // block for when val1 == true (don't even evaluate the second part)
3509     Stage1ZirBasicBlock *true_block = ir_create_basic_block(ag, scope, "BoolOrTrue");
3510 
3511     ir_build_cond_br(ag, scope, node, val1, true_block, false_block, is_comptime);
3512 
3513     ir_set_cursor_at_end_and_append_block(ag, false_block);
3514     Stage1ZirInst *val2 = astgen_node(ag, node->data.bin_op_expr.op2, scope);
3515     if (val2 == ag->codegen->invalid_inst_src)
3516         return ag->codegen->invalid_inst_src;
3517     Stage1ZirBasicBlock *post_val2_block = ag->current_basic_block;
3518 
3519     ir_build_br(ag, scope, node, true_block, is_comptime);
3520 
3521     ir_set_cursor_at_end_and_append_block(ag, true_block);
3522 
3523     Stage1ZirInst **incoming_values = heap::c_allocator.allocate<Stage1ZirInst *>(2);
3524     incoming_values[0] = val1;
3525     incoming_values[1] = val2;
3526     Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
3527     incoming_blocks[0] = post_val1_block;
3528     incoming_blocks[1] = post_val2_block;
3529 
3530     return ir_build_phi(ag, scope, node, 2, incoming_blocks, incoming_values, nullptr);
3531 }
3532 
astgen_bool_and(Stage1AstGen * ag,Scope * scope,AstNode * node)3533 static Stage1ZirInst *astgen_bool_and(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3534     assert(node->type == NodeTypeBinOpExpr);
3535 
3536     Stage1ZirInst *val1 = astgen_node(ag, node->data.bin_op_expr.op1, scope);
3537     if (val1 == ag->codegen->invalid_inst_src)
3538         return ag->codegen->invalid_inst_src;
3539     Stage1ZirBasicBlock *post_val1_block = ag->current_basic_block;
3540 
3541     Stage1ZirInst *is_comptime;
3542     if (ir_should_inline(ag->exec, scope)) {
3543         is_comptime = ir_build_const_bool(ag, scope, node, true);
3544     } else {
3545         is_comptime = ir_build_test_comptime(ag, scope, node, val1);
3546     }
3547 
3548     // block for when val1 == true
3549     Stage1ZirBasicBlock *true_block = ir_create_basic_block(ag, scope, "BoolAndTrue");
3550     // block for when val1 == false (don't even evaluate the second part)
3551     Stage1ZirBasicBlock *false_block = ir_create_basic_block(ag, scope, "BoolAndFalse");
3552 
3553     ir_build_cond_br(ag, scope, node, val1, true_block, false_block, is_comptime);
3554 
3555     ir_set_cursor_at_end_and_append_block(ag, true_block);
3556     Stage1ZirInst *val2 = astgen_node(ag, node->data.bin_op_expr.op2, scope);
3557     if (val2 == ag->codegen->invalid_inst_src)
3558         return ag->codegen->invalid_inst_src;
3559     Stage1ZirBasicBlock *post_val2_block = ag->current_basic_block;
3560 
3561     ir_build_br(ag, scope, node, false_block, is_comptime);
3562 
3563     ir_set_cursor_at_end_and_append_block(ag, false_block);
3564 
3565     Stage1ZirInst **incoming_values = heap::c_allocator.allocate<Stage1ZirInst *>(2);
3566     incoming_values[0] = val1;
3567     incoming_values[1] = val2;
3568     Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
3569     incoming_blocks[0] = post_val1_block;
3570     incoming_blocks[1] = post_val2_block;
3571 
3572     return ir_build_phi(ag, scope, node, 2, incoming_blocks, incoming_values, nullptr);
3573 }
3574 
ir_build_result_peers(Stage1AstGen * ag,Stage1ZirInst * cond_br_inst,Stage1ZirBasicBlock * end_block,ResultLoc * parent,Stage1ZirInst * is_comptime)3575 static ResultLocPeerParent *ir_build_result_peers(Stage1AstGen *ag, Stage1ZirInst *cond_br_inst,
3576         Stage1ZirBasicBlock *end_block, ResultLoc *parent, Stage1ZirInst *is_comptime)
3577 {
3578     ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
3579     peer_parent->base.id = ResultLocIdPeerParent;
3580     peer_parent->base.source_instruction = cond_br_inst;
3581     peer_parent->base.allow_write_through_const = parent->allow_write_through_const;
3582     peer_parent->end_bb = end_block;
3583     peer_parent->is_comptime = is_comptime;
3584     peer_parent->parent = parent;
3585 
3586     Stage1ZirInst *popped_inst = ag->current_basic_block->instruction_list.pop();
3587     ir_assert(popped_inst == cond_br_inst, cond_br_inst);
3588 
3589     ir_build_reset_result(ag, cond_br_inst->scope, cond_br_inst->source_node, &peer_parent->base);
3590     ag->current_basic_block->instruction_list.append(popped_inst);
3591 
3592     return peer_parent;
3593 }
3594 
ir_build_binary_result_peers(Stage1AstGen * ag,Stage1ZirInst * cond_br_inst,Stage1ZirBasicBlock * else_block,Stage1ZirBasicBlock * end_block,ResultLoc * parent,Stage1ZirInst * is_comptime)3595 static ResultLocPeerParent *ir_build_binary_result_peers(Stage1AstGen *ag, Stage1ZirInst *cond_br_inst,
3596         Stage1ZirBasicBlock *else_block, Stage1ZirBasicBlock *end_block, ResultLoc *parent, Stage1ZirInst *is_comptime)
3597 {
3598     ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, parent, is_comptime);
3599 
3600     peer_parent->peers.append(create_peer_result(peer_parent));
3601     peer_parent->peers.last()->next_bb = else_block;
3602 
3603     peer_parent->peers.append(create_peer_result(peer_parent));
3604     peer_parent->peers.last()->next_bb = end_block;
3605 
3606     return peer_parent;
3607 }
3608 
astgen_orelse(Stage1AstGen * ag,Scope * parent_scope,AstNode * node,LVal lval,ResultLoc * result_loc)3609 static Stage1ZirInst *astgen_orelse(Stage1AstGen *ag, Scope *parent_scope, AstNode *node, LVal lval,
3610         ResultLoc *result_loc)
3611 {
3612     assert(node->type == NodeTypeBinOpExpr);
3613 
3614     AstNode *op1_node = node->data.bin_op_expr.op1;
3615     AstNode *op2_node = node->data.bin_op_expr.op2;
3616 
3617     Stage1ZirInst *maybe_ptr = astgen_node_extra(ag, op1_node, parent_scope, LValPtr, nullptr);
3618     if (maybe_ptr == ag->codegen->invalid_inst_src)
3619         return ag->codegen->invalid_inst_src;
3620 
3621     Stage1ZirInst *maybe_val = ir_build_load_ptr(ag, parent_scope, node, maybe_ptr);
3622     Stage1ZirInst *is_non_null = ir_build_test_non_null_src(ag, parent_scope, node, maybe_val);
3623 
3624     Stage1ZirInst *is_comptime;
3625     if (ir_should_inline(ag->exec, parent_scope)) {
3626         is_comptime = ir_build_const_bool(ag, parent_scope, node, true);
3627     } else {
3628         is_comptime = ir_build_test_comptime(ag, parent_scope, node, is_non_null);
3629     }
3630 
3631     Stage1ZirBasicBlock *ok_block = ir_create_basic_block(ag, parent_scope, "OptionalNonNull");
3632     Stage1ZirBasicBlock *null_block = ir_create_basic_block(ag, parent_scope, "OptionalNull");
3633     Stage1ZirBasicBlock *end_block = ir_create_basic_block(ag, parent_scope, "OptionalEnd");
3634     Stage1ZirInst *cond_br_inst = ir_build_cond_br(ag, parent_scope, node, is_non_null, ok_block, null_block, is_comptime);
3635 
3636     ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(ag, cond_br_inst, ok_block, end_block,
3637             result_loc, is_comptime);
3638 
3639     ir_set_cursor_at_end_and_append_block(ag, null_block);
3640     Stage1ZirInst *null_result = astgen_node_extra(ag, op2_node, parent_scope, LValNone,
3641             &peer_parent->peers.at(0)->base);
3642     if (null_result == ag->codegen->invalid_inst_src)
3643         return ag->codegen->invalid_inst_src;
3644     Stage1ZirBasicBlock *after_null_block = ag->current_basic_block;
3645     if (!instr_is_unreachable(null_result))
3646         ir_build_br(ag, parent_scope, node, end_block, is_comptime);
3647 
3648     ir_set_cursor_at_end_and_append_block(ag, ok_block);
3649     Stage1ZirInst *unwrapped_ptr = ir_build_optional_unwrap_ptr(ag, parent_scope, node, maybe_ptr, false);
3650     Stage1ZirInst *unwrapped_payload = ir_build_load_ptr(ag, parent_scope, node, unwrapped_ptr);
3651     ir_build_end_expr(ag, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base);
3652     Stage1ZirBasicBlock *after_ok_block = ag->current_basic_block;
3653     ir_build_br(ag, parent_scope, node, end_block, is_comptime);
3654 
3655     ir_set_cursor_at_end_and_append_block(ag, end_block);
3656     Stage1ZirInst **incoming_values = heap::c_allocator.allocate<Stage1ZirInst *>(2);
3657     incoming_values[0] = null_result;
3658     incoming_values[1] = unwrapped_payload;
3659     Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
3660     incoming_blocks[0] = after_null_block;
3661     incoming_blocks[1] = after_ok_block;
3662     Stage1ZirInst *phi = ir_build_phi(ag, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
3663     return ir_lval_wrap(ag, parent_scope, phi, lval, result_loc);
3664 }
3665 
astgen_error_union(Stage1AstGen * ag,Scope * parent_scope,AstNode * node)3666 static Stage1ZirInst *astgen_error_union(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
3667     assert(node->type == NodeTypeBinOpExpr);
3668 
3669     AstNode *op1_node = node->data.bin_op_expr.op1;
3670     AstNode *op2_node = node->data.bin_op_expr.op2;
3671 
3672     Stage1ZirInst *err_set = astgen_node(ag, op1_node, parent_scope);
3673     if (err_set == ag->codegen->invalid_inst_src)
3674         return ag->codegen->invalid_inst_src;
3675 
3676     Stage1ZirInst *payload = astgen_node(ag, op2_node, parent_scope);
3677     if (payload == ag->codegen->invalid_inst_src)
3678         return ag->codegen->invalid_inst_src;
3679 
3680     return ir_build_error_union(ag, parent_scope, node, err_set, payload);
3681 }
3682 
astgen_bin_op(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)3683 static Stage1ZirInst *astgen_bin_op(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
3684     assert(node->type == NodeTypeBinOpExpr);
3685 
3686     BinOpType bin_op_type = node->data.bin_op_expr.bin_op;
3687     switch (bin_op_type) {
3688         case BinOpTypeInvalid:
3689             zig_unreachable();
3690         case BinOpTypeAssign:
3691             return ir_lval_wrap(ag, scope, astgen_assign(ag, scope, node), lval, result_loc);
3692         case BinOpTypeAssignTimes:
3693             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpMult), lval, result_loc);
3694         case BinOpTypeAssignTimesWrap:
3695             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpMultWrap), lval, result_loc);
3696         case BinOpTypeAssignTimesSat:
3697             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpMultSat), lval, result_loc);
3698         case BinOpTypeAssignDiv:
3699             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpDivUnspecified), lval, result_loc);
3700         case BinOpTypeAssignMod:
3701             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpRemUnspecified), lval, result_loc);
3702         case BinOpTypeAssignPlus:
3703             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpAdd), lval, result_loc);
3704         case BinOpTypeAssignPlusWrap:
3705             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpAddWrap), lval, result_loc);
3706         case BinOpTypeAssignPlusSat:
3707             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpAddSat), lval, result_loc);
3708         case BinOpTypeAssignMinus:
3709             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpSub), lval, result_loc);
3710         case BinOpTypeAssignMinusWrap:
3711             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpSubWrap), lval, result_loc);
3712         case BinOpTypeAssignMinusSat:
3713             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpSubSat), lval, result_loc);
3714         case BinOpTypeAssignBitShiftLeft:
3715             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc);
3716         case BinOpTypeAssignBitShiftLeftSat:
3717             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpShlSat), lval, result_loc);
3718         case BinOpTypeAssignBitShiftRight:
3719             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc);
3720         case BinOpTypeAssignBitAnd:
3721             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpBinAnd), lval, result_loc);
3722         case BinOpTypeAssignBitXor:
3723             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpBinXor), lval, result_loc);
3724         case BinOpTypeAssignBitOr:
3725             return ir_lval_wrap(ag, scope, astgen_assign_op(ag, scope, node, IrBinOpBinOr), lval, result_loc);
3726         case BinOpTypeBoolOr:
3727             return ir_lval_wrap(ag, scope, astgen_bool_or(ag, scope, node), lval, result_loc);
3728         case BinOpTypeBoolAnd:
3729             return ir_lval_wrap(ag, scope, astgen_bool_and(ag, scope, node), lval, result_loc);
3730         case BinOpTypeCmpEq:
3731             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpEq), lval, result_loc);
3732         case BinOpTypeCmpNotEq:
3733             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpNotEq), lval, result_loc);
3734         case BinOpTypeCmpLessThan:
3735             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpLessThan), lval, result_loc);
3736         case BinOpTypeCmpGreaterThan:
3737             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpGreaterThan), lval, result_loc);
3738         case BinOpTypeCmpLessOrEq:
3739             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpLessOrEq), lval, result_loc);
3740         case BinOpTypeCmpGreaterOrEq:
3741             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc);
3742         case BinOpTypeBinOr:
3743             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpBinOr), lval, result_loc);
3744         case BinOpTypeBinXor:
3745             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpBinXor), lval, result_loc);
3746         case BinOpTypeBinAnd:
3747             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpBinAnd), lval, result_loc);
3748         case BinOpTypeBitShiftLeft:
3749             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc);
3750         case BinOpTypeBitShiftLeftSat:
3751             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpShlSat), lval, result_loc);
3752         case BinOpTypeBitShiftRight:
3753             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc);
3754         case BinOpTypeAdd:
3755             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpAdd), lval, result_loc);
3756         case BinOpTypeAddWrap:
3757             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpAddWrap), lval, result_loc);
3758         case BinOpTypeAddSat:
3759             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpAddSat), lval, result_loc);
3760         case BinOpTypeSub:
3761             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpSub), lval, result_loc);
3762         case BinOpTypeSubWrap:
3763             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpSubWrap), lval, result_loc);
3764         case BinOpTypeSubSat:
3765             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpSubSat), lval, result_loc);
3766         case BinOpTypeMult:
3767             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpMult), lval, result_loc);
3768         case BinOpTypeMultWrap:
3769             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpMultWrap), lval, result_loc);
3770         case BinOpTypeMultSat:
3771             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpMultSat), lval, result_loc);
3772         case BinOpTypeDiv:
3773             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpDivUnspecified), lval, result_loc);
3774         case BinOpTypeMod:
3775             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpRemUnspecified), lval, result_loc);
3776         case BinOpTypeArrayCat:
3777             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpArrayCat), lval, result_loc);
3778         case BinOpTypeArrayMult:
3779             return ir_lval_wrap(ag, scope, astgen_bin_op_id(ag, scope, node, IrBinOpArrayMult), lval, result_loc);
3780         case BinOpTypeMergeErrorSets:
3781             return ir_lval_wrap(ag, scope, astgen_merge_err_sets(ag, scope, node), lval, result_loc);
3782         case BinOpTypeUnwrapOptional:
3783             return astgen_orelse(ag, scope, node, lval, result_loc);
3784         case BinOpTypeErrorUnion:
3785             return ir_lval_wrap(ag, scope, astgen_error_union(ag, scope, node), lval, result_loc);
3786     }
3787     zig_unreachable();
3788 }
3789 
astgen_int_lit(Stage1AstGen * ag,Scope * scope,AstNode * node)3790 static Stage1ZirInst *astgen_int_lit(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3791     assert(node->type == NodeTypeIntLiteral);
3792 
3793     RootStruct *root_struct = node->owner->data.structure.root_struct;
3794     BigInt bigint;
3795     token_number_literal_bigint(root_struct, &bigint, node->main_token);
3796     return ir_build_const_bigint(ag, scope, node, bigint);
3797 }
3798 
astgen_float_lit(Stage1AstGen * ag,Scope * scope,AstNode * node)3799 static Stage1ZirInst *astgen_float_lit(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3800     Error err;
3801     assert(node->type == NodeTypeFloatLiteral);
3802 
3803     RootStruct *root_struct = node->owner->data.structure.root_struct;
3804     const char *source = buf_ptr(root_struct->source_code);
3805     uint32_t byte_offset = root_struct->token_locs[node->main_token].offset;
3806 
3807     BigFloat bigfloat;
3808     if ((err = bigfloat_init_buf(&bigfloat, (const uint8_t *)source + byte_offset))) {
3809         add_node_error(ag->codegen, node, buf_sprintf("float literal out of range of any type"));
3810         return ag->codegen->invalid_inst_src;
3811     }
3812 
3813     return ir_build_const_bigfloat(ag, scope, node, bigfloat);
3814 }
3815 
astgen_char_lit(Stage1AstGen * ag,Scope * scope,AstNode * node)3816 static Stage1ZirInst *astgen_char_lit(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3817     Error err;
3818     assert(node->type == NodeTypeCharLiteral);
3819 
3820     RootStruct *root_struct = node->owner->data.structure.root_struct;
3821     const char *source = buf_ptr(root_struct->source_code);
3822     uint32_t byte_offset = root_struct->token_locs[node->main_token].offset;
3823 
3824     src_assert(source[byte_offset] == '\'', node);
3825     byte_offset += 1;
3826 
3827     uint32_t codepoint;
3828     size_t bad_index;
3829     if ((err = source_char_literal(source + byte_offset, &codepoint, &bad_index))) {
3830         add_node_error(ag->codegen, node, buf_sprintf("invalid character"));
3831         return ag->codegen->invalid_inst_src;
3832     }
3833     return ir_build_const_uint(ag, scope, node, codepoint);
3834 }
3835 
astgen_null_literal(Stage1AstGen * ag,Scope * scope,AstNode * node)3836 static Stage1ZirInst *astgen_null_literal(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3837     assert(node->type == NodeTypeNullLiteral);
3838 
3839     return ir_build_const_null(ag, scope, node);
3840 }
3841 
astgen_identifier(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)3842 static Stage1ZirInst *astgen_identifier(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
3843         ResultLoc *result_loc)
3844 {
3845     Error err;
3846     assert(node->type == NodeTypeIdentifier);
3847 
3848     bool is_at_syntax;
3849     Buf *variable_name = node_identifier_buf2(node, &is_at_syntax);
3850 
3851     if (!is_at_syntax) {
3852         if (buf_eql_str(variable_name, "_")) {
3853             if (lval == LValAssign) {
3854                 Stage1ZirInstConst *const_instruction = ir_build_instruction<Stage1ZirInstConst>(ag, scope, node);
3855                 const_instruction->value = ag->codegen->pass1_arena->create<ZigValue>();
3856                 const_instruction->value->type = get_pointer_to_type(ag->codegen,
3857                         ag->codegen->builtin_types.entry_void, false);
3858                 const_instruction->value->special = ConstValSpecialStatic;
3859                 const_instruction->value->data.x_ptr.special = ConstPtrSpecialDiscard;
3860                 return &const_instruction->base;
3861             }
3862         }
3863 
3864         ZigType *primitive_type;
3865         if ((err = get_primitive_type(ag->codegen, variable_name, &primitive_type))) {
3866             if (err == ErrorOverflow) {
3867                 add_node_error(ag->codegen, node,
3868                     buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535",
3869                         buf_ptr(variable_name)));
3870                 return ag->codegen->invalid_inst_src;
3871             }
3872             assert(err == ErrorPrimitiveTypeNotFound);
3873         } else {
3874             Stage1ZirInst *value = ir_build_const_type(ag, scope, node, primitive_type);
3875             if (lval == LValPtr || lval == LValAssign) {
3876                 return ir_build_ref_src(ag, scope, node, value);
3877             } else {
3878                 return ir_expr_wrap(ag, scope, value, result_loc);
3879             }
3880         }
3881     }
3882 
3883     ScopeFnDef *crossed_fndef_scope;
3884     ZigVar *var = find_variable(ag->codegen, scope, variable_name, &crossed_fndef_scope);
3885     if (var) {
3886         Stage1ZirInst *var_ptr = ir_build_var_ptr_x(ag, scope, node, var, crossed_fndef_scope);
3887         if (lval == LValPtr || lval == LValAssign) {
3888             return var_ptr;
3889         } else {
3890             return ir_expr_wrap(ag, scope, ir_build_load_ptr(ag, scope, node, var_ptr), result_loc);
3891         }
3892     }
3893 
3894     Tld *tld = nullptr;
3895     {
3896         Scope *s = scope;
3897         while (s) {
3898             if (s->id == ScopeIdDecls) {
3899                 ScopeDecls *decls_scope = (ScopeDecls *)s;
3900 
3901                 Tld *result = find_container_decl(ag->codegen, decls_scope, variable_name);
3902                 if (result != nullptr) {
3903                     if (tld != nullptr && tld != result) {
3904                         ErrorMsg *msg = add_node_error(ag->codegen, node,
3905                                 buf_sprintf("ambiguous reference"));
3906                         add_error_note(ag->codegen, msg, tld->source_node,
3907                                 buf_sprintf("declared here"));
3908                         add_error_note(ag->codegen, msg, result->source_node,
3909                                 buf_sprintf("also declared here"));
3910                         return ag->codegen->invalid_inst_src;
3911                     }
3912                     tld = result;
3913                 }
3914             }
3915             s = s->parent;
3916         }
3917     }
3918 
3919     if (tld) {
3920         Stage1ZirInst *decl_ref = ir_build_decl_ref(ag, scope, node, tld, lval);
3921         if (lval == LValPtr || lval == LValAssign) {
3922             return decl_ref;
3923         } else {
3924             return ir_expr_wrap(ag, scope, decl_ref, result_loc);
3925         }
3926     }
3927 
3928     if (get_container_scope(node->owner)->any_imports_failed) {
3929         // skip the error message since we had a failing import in this file
3930         // if an import breaks we don't need redundant undeclared identifier errors
3931         return ag->codegen->invalid_inst_src;
3932     }
3933 
3934     return ir_build_undeclared_identifier(ag, scope, node, variable_name);
3935 }
3936 
astgen_array_access(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)3937 static Stage1ZirInst *astgen_array_access(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
3938         ResultLoc *result_loc)
3939 {
3940     assert(node->type == NodeTypeArrayAccessExpr);
3941 
3942     AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr;
3943     Stage1ZirInst *array_ref_instruction = astgen_node_extra(ag, array_ref_node, scope, LValPtr, nullptr);
3944     if (array_ref_instruction == ag->codegen->invalid_inst_src)
3945         return array_ref_instruction;
3946 
3947     // Create an usize-typed result location to hold the subscript value, this
3948     // makes it possible for the compiler to infer the subscript expression type
3949     // if needed
3950     Stage1ZirInst *usize_type_inst = ir_build_const_type(ag, scope, node, ag->codegen->builtin_types.entry_usize);
3951     ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, usize_type_inst, no_result_loc());
3952 
3953     AstNode *subscript_node = node->data.array_access_expr.subscript;
3954     Stage1ZirInst *subscript_value = astgen_node_extra(ag, subscript_node, scope, LValNone, &result_loc_cast->base);
3955     if (subscript_value == ag->codegen->invalid_inst_src)
3956         return ag->codegen->invalid_inst_src;
3957 
3958     Stage1ZirInst *subscript_instruction = ir_build_implicit_cast(ag, scope, subscript_node, subscript_value, result_loc_cast);
3959 
3960     Stage1ZirInst *ptr_instruction = ir_build_elem_ptr(ag, scope, node, array_ref_instruction,
3961             subscript_instruction, true, PtrLenSingle, nullptr);
3962     if (lval == LValPtr || lval == LValAssign)
3963         return ptr_instruction;
3964 
3965     Stage1ZirInst *load_ptr = ir_build_load_ptr(ag, scope, node, ptr_instruction);
3966     return ir_expr_wrap(ag, scope, load_ptr, result_loc);
3967 }
3968 
astgen_field_access(Stage1AstGen * ag,Scope * scope,AstNode * node)3969 static Stage1ZirInst *astgen_field_access(Stage1AstGen *ag, Scope *scope, AstNode *node) {
3970     assert(node->type == NodeTypeFieldAccessExpr);
3971 
3972     AstNode *container_ref_node = node->data.field_access_expr.struct_expr;
3973     Buf *field_name = node->data.field_access_expr.field_name;
3974 
3975     Stage1ZirInst *container_ref_instruction = astgen_node_extra(ag, container_ref_node, scope, LValPtr, nullptr);
3976     if (container_ref_instruction == ag->codegen->invalid_inst_src)
3977         return container_ref_instruction;
3978 
3979     return ir_build_field_ptr(ag, scope, node, container_ref_instruction, field_name, false);
3980 }
3981 
astgen_overflow_op(Stage1AstGen * ag,Scope * scope,AstNode * node,IrOverflowOp op)3982 static Stage1ZirInst *astgen_overflow_op(Stage1AstGen *ag, Scope *scope, AstNode *node, IrOverflowOp op) {
3983     assert(node->type == NodeTypeFnCallExpr);
3984 
3985     AstNode *type_node = node->data.fn_call_expr.params.at(0);
3986     AstNode *op1_node = node->data.fn_call_expr.params.at(1);
3987     AstNode *op2_node = node->data.fn_call_expr.params.at(2);
3988     AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3);
3989 
3990 
3991     Stage1ZirInst *type_value = astgen_node(ag, type_node, scope);
3992     if (type_value == ag->codegen->invalid_inst_src)
3993         return ag->codegen->invalid_inst_src;
3994 
3995     Stage1ZirInst *op1 = astgen_node(ag, op1_node, scope);
3996     if (op1 == ag->codegen->invalid_inst_src)
3997         return ag->codegen->invalid_inst_src;
3998 
3999     Stage1ZirInst *op2 = astgen_node(ag, op2_node, scope);
4000     if (op2 == ag->codegen->invalid_inst_src)
4001         return ag->codegen->invalid_inst_src;
4002 
4003     Stage1ZirInst *result_ptr = astgen_node(ag, result_ptr_node, scope);
4004     if (result_ptr == ag->codegen->invalid_inst_src)
4005         return ag->codegen->invalid_inst_src;
4006 
4007     return ir_build_overflow_op_src(ag, scope, node, op, type_value, op1, op2, result_ptr);
4008 }
4009 
astgen_mul_add(Stage1AstGen * ag,Scope * scope,AstNode * node)4010 static Stage1ZirInst *astgen_mul_add(Stage1AstGen *ag, Scope *scope, AstNode *node) {
4011     assert(node->type == NodeTypeFnCallExpr);
4012 
4013     AstNode *type_node = node->data.fn_call_expr.params.at(0);
4014     AstNode *op1_node = node->data.fn_call_expr.params.at(1);
4015     AstNode *op2_node = node->data.fn_call_expr.params.at(2);
4016     AstNode *op3_node = node->data.fn_call_expr.params.at(3);
4017 
4018     Stage1ZirInst *type_value = astgen_node(ag, type_node, scope);
4019     if (type_value == ag->codegen->invalid_inst_src)
4020         return ag->codegen->invalid_inst_src;
4021 
4022     Stage1ZirInst *op1 = astgen_node(ag, op1_node, scope);
4023     if (op1 == ag->codegen->invalid_inst_src)
4024         return ag->codegen->invalid_inst_src;
4025 
4026     Stage1ZirInst *op2 = astgen_node(ag, op2_node, scope);
4027     if (op2 == ag->codegen->invalid_inst_src)
4028         return ag->codegen->invalid_inst_src;
4029 
4030     Stage1ZirInst *op3 = astgen_node(ag, op3_node, scope);
4031     if (op3 == ag->codegen->invalid_inst_src)
4032         return ag->codegen->invalid_inst_src;
4033 
4034     return ir_build_mul_add_src(ag, scope, node, type_value, op1, op2, op3);
4035 }
4036 
astgen_this(Stage1AstGen * ag,Scope * orig_scope,AstNode * node)4037 static Stage1ZirInst *astgen_this(Stage1AstGen *ag, Scope *orig_scope, AstNode *node) {
4038     for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) {
4039         if (it_scope->id == ScopeIdDecls) {
4040             ScopeDecls *decls_scope = (ScopeDecls *)it_scope;
4041             ZigType *container_type = decls_scope->container_type;
4042             if (container_type != nullptr) {
4043                 return ir_build_const_type(ag, orig_scope, node, container_type);
4044             } else {
4045                 return ir_build_const_import(ag, orig_scope, node, decls_scope->import);
4046             }
4047         }
4048     }
4049     zig_unreachable();
4050 }
4051 
astgen_async_call(Stage1AstGen * ag,Scope * scope,AstNode * await_node,AstNode * call_node,LVal lval,ResultLoc * result_loc)4052 static Stage1ZirInst *astgen_async_call(Stage1AstGen *ag, Scope *scope, AstNode *await_node, AstNode *call_node,
4053         LVal lval, ResultLoc *result_loc)
4054 {
4055     if (call_node->data.fn_call_expr.params.length != 4) {
4056         add_node_error(ag->codegen, call_node,
4057             buf_sprintf("expected 4 arguments, found %" ZIG_PRI_usize,
4058                 call_node->data.fn_call_expr.params.length));
4059         return ag->codegen->invalid_inst_src;
4060     }
4061 
4062     AstNode *bytes_node = call_node->data.fn_call_expr.params.at(0);
4063     Stage1ZirInst *bytes = astgen_node(ag, bytes_node, scope);
4064     if (bytes == ag->codegen->invalid_inst_src)
4065         return bytes;
4066 
4067     AstNode *ret_ptr_node = call_node->data.fn_call_expr.params.at(1);
4068     Stage1ZirInst *ret_ptr = astgen_node(ag, ret_ptr_node, scope);
4069     if (ret_ptr == ag->codegen->invalid_inst_src)
4070         return ret_ptr;
4071 
4072     AstNode *fn_ref_node = call_node->data.fn_call_expr.params.at(2);
4073     Stage1ZirInst *fn_ref = astgen_node(ag, fn_ref_node, scope);
4074     if (fn_ref == ag->codegen->invalid_inst_src)
4075         return fn_ref;
4076 
4077     CallModifier modifier = (await_node == nullptr) ? CallModifierAsync : CallModifierNone;
4078     bool is_async_call_builtin = true;
4079     AstNode *args_node = call_node->data.fn_call_expr.params.at(3);
4080     if (args_node->type == NodeTypeContainerInitExpr) {
4081         if (args_node->data.container_init_expr.kind == ContainerInitKindArray ||
4082             args_node->data.container_init_expr.entries.length == 0)
4083         {
4084             size_t arg_count = args_node->data.container_init_expr.entries.length;
4085             Stage1ZirInst **args = heap::c_allocator.allocate<Stage1ZirInst*>(arg_count);
4086             for (size_t i = 0; i < arg_count; i += 1) {
4087                 AstNode *arg_node = args_node->data.container_init_expr.entries.at(i);
4088                 Stage1ZirInst *arg = astgen_node(ag, arg_node, scope);
4089                 if (arg == ag->codegen->invalid_inst_src)
4090                     return arg;
4091                 args[i] = arg;
4092             }
4093 
4094             Stage1ZirInst *call = ir_build_call_src(ag, scope, call_node, nullptr, fn_ref, arg_count, args,
4095                 ret_ptr, modifier, is_async_call_builtin, bytes, result_loc);
4096             return ir_lval_wrap(ag, scope, call, lval, result_loc);
4097         } else {
4098             exec_add_error_node(ag->codegen, ag->exec, args_node,
4099                     buf_sprintf("TODO: @asyncCall with anon struct literal"));
4100             return ag->codegen->invalid_inst_src;
4101         }
4102     }
4103     Stage1ZirInst *args = astgen_node(ag, args_node, scope);
4104     if (args == ag->codegen->invalid_inst_src)
4105         return args;
4106 
4107     Stage1ZirInst *call = ir_build_async_call_extra(ag, scope, call_node, modifier, fn_ref, ret_ptr, bytes, args, result_loc);
4108     return ir_lval_wrap(ag, scope, call, lval, result_loc);
4109 }
4110 
astgen_fn_call_with_args(Stage1AstGen * ag,Scope * scope,AstNode * source_node,AstNode * fn_ref_node,CallModifier modifier,Stage1ZirInst * options,AstNode ** args_ptr,size_t args_len,LVal lval,ResultLoc * result_loc)4111 static Stage1ZirInst *astgen_fn_call_with_args(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
4112         AstNode *fn_ref_node, CallModifier modifier, Stage1ZirInst *options,
4113         AstNode **args_ptr, size_t args_len, LVal lval, ResultLoc *result_loc)
4114 {
4115     Stage1ZirInst *fn_ref = astgen_node(ag, fn_ref_node, scope);
4116     if (fn_ref == ag->codegen->invalid_inst_src)
4117         return fn_ref;
4118 
4119     Stage1ZirInst *fn_type = ir_build_typeof_1(ag, scope, source_node, fn_ref);
4120 
4121     Stage1ZirInst **args = heap::c_allocator.allocate<Stage1ZirInst*>(args_len);
4122     for (size_t i = 0; i < args_len; i += 1) {
4123         AstNode *arg_node = args_ptr[i];
4124 
4125         Stage1ZirInst *arg_index = ir_build_const_usize(ag, scope, arg_node, i);
4126         Stage1ZirInst *arg_type = ir_build_arg_type(ag, scope, source_node, fn_type, arg_index, true);
4127         ResultLoc *no_result = no_result_loc();
4128         ir_build_reset_result(ag, scope, source_node, no_result);
4129         ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, arg_type, no_result);
4130 
4131         Stage1ZirInst *arg = astgen_node_extra(ag, arg_node, scope, LValNone, &result_loc_cast->base);
4132         if (arg == ag->codegen->invalid_inst_src)
4133             return arg;
4134 
4135         args[i] = ir_build_implicit_cast(ag, scope, arg_node, arg, result_loc_cast);
4136     }
4137 
4138     Stage1ZirInst *fn_call;
4139     if (options != nullptr) {
4140         fn_call = ir_build_call_args(ag, scope, source_node, options, fn_ref, args, args_len, result_loc);
4141     } else {
4142         fn_call = ir_build_call_src(ag, scope, source_node, nullptr, fn_ref, args_len, args, nullptr,
4143                 modifier, false, nullptr, result_loc);
4144     }
4145     return ir_lval_wrap(ag, scope, fn_call, lval, result_loc);
4146 }
4147 
astgen_builtin_fn_call(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)4148 static Stage1ZirInst *astgen_builtin_fn_call(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
4149         ResultLoc *result_loc)
4150 {
4151     assert(node->type == NodeTypeFnCallExpr);
4152 
4153     AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
4154     Buf *name = node_identifier_buf(fn_ref_expr);
4155     auto entry = ag->codegen->builtin_fn_table.maybe_get(name);
4156 
4157     if (!entry) {
4158         add_node_error(ag->codegen, node,
4159                 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name)));
4160         return ag->codegen->invalid_inst_src;
4161     }
4162 
4163     BuiltinFnEntry *builtin_fn = entry->value;
4164     size_t actual_param_count = node->data.fn_call_expr.params.length;
4165 
4166     if (builtin_fn->param_count != SIZE_MAX && builtin_fn->param_count != actual_param_count) {
4167         add_node_error(ag->codegen, node,
4168                 buf_sprintf("expected %" ZIG_PRI_usize " argument(s), found %" ZIG_PRI_usize,
4169                     builtin_fn->param_count, actual_param_count));
4170         return ag->codegen->invalid_inst_src;
4171     }
4172 
4173     switch (builtin_fn->id) {
4174         case BuiltinFnIdInvalid:
4175             zig_unreachable();
4176         case BuiltinFnIdTypeof:
4177             {
4178                 Scope *sub_scope = create_typeof_scope(ag->codegen, node, scope);
4179 
4180                 size_t arg_count = node->data.fn_call_expr.params.length;
4181 
4182                 Stage1ZirInst *type_of;
4183 
4184                 if (arg_count == 0) {
4185                     add_node_error(ag->codegen, node,
4186                         buf_sprintf("expected at least 1 argument, found 0"));
4187                     return ag->codegen->invalid_inst_src;
4188                 } else if (arg_count == 1) {
4189                     AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4190                     Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, sub_scope);
4191                     if (arg0_value == ag->codegen->invalid_inst_src)
4192                         return arg0_value;
4193 
4194                     type_of = ir_build_typeof_1(ag, scope, node, arg0_value);
4195                 } else {
4196                     Stage1ZirInst **args = heap::c_allocator.allocate<Stage1ZirInst*>(arg_count);
4197                     for (size_t i = 0; i < arg_count; i += 1) {
4198                         AstNode *arg_node = node->data.fn_call_expr.params.at(i);
4199                         Stage1ZirInst *arg = astgen_node(ag, arg_node, sub_scope);
4200                         if (arg == ag->codegen->invalid_inst_src)
4201                             return ag->codegen->invalid_inst_src;
4202                         args[i] = arg;
4203                     }
4204 
4205                     type_of = ir_build_typeof_n(ag, scope, node, args, arg_count);
4206                 }
4207                 return ir_lval_wrap(ag, scope, type_of, lval, result_loc);
4208             }
4209         case BuiltinFnIdSetCold:
4210             {
4211                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4212                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4213                 if (arg0_value == ag->codegen->invalid_inst_src)
4214                     return arg0_value;
4215 
4216                 Stage1ZirInst *set_cold = ir_build_set_cold(ag, scope, node, arg0_value);
4217                 return ir_lval_wrap(ag, scope, set_cold, lval, result_loc);
4218             }
4219         case BuiltinFnIdSetRuntimeSafety:
4220             {
4221                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4222                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4223                 if (arg0_value == ag->codegen->invalid_inst_src)
4224                     return arg0_value;
4225 
4226                 Stage1ZirInst *set_safety = ir_build_set_runtime_safety(ag, scope, node, arg0_value);
4227                 return ir_lval_wrap(ag, scope, set_safety, lval, result_loc);
4228             }
4229         case BuiltinFnIdSetFloatMode:
4230             {
4231                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4232                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4233                 if (arg0_value == ag->codegen->invalid_inst_src)
4234                     return arg0_value;
4235 
4236                 Stage1ZirInst *set_float_mode = ir_build_set_float_mode(ag, scope, node, arg0_value);
4237                 return ir_lval_wrap(ag, scope, set_float_mode, lval, result_loc);
4238             }
4239         case BuiltinFnIdSizeof:
4240         case BuiltinFnIdBitSizeof:
4241             {
4242                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4243                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4244                 if (arg0_value == ag->codegen->invalid_inst_src)
4245                     return arg0_value;
4246 
4247                 Stage1ZirInst *size_of = ir_build_size_of(ag, scope, node, arg0_value, builtin_fn->id == BuiltinFnIdBitSizeof);
4248                 return ir_lval_wrap(ag, scope, size_of, lval, result_loc);
4249             }
4250         case BuiltinFnIdImport:
4251             {
4252                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4253                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4254                 if (arg0_value == ag->codegen->invalid_inst_src)
4255                     return arg0_value;
4256 
4257                 Stage1ZirInst *import = ir_build_import(ag, scope, node, arg0_value);
4258                 return ir_lval_wrap(ag, scope, import, lval, result_loc);
4259             }
4260         case BuiltinFnIdCImport:
4261             {
4262                 Stage1ZirInst *c_import = ir_build_c_import(ag, scope, node);
4263                 return ir_lval_wrap(ag, scope, c_import, lval, result_loc);
4264             }
4265         case BuiltinFnIdCInclude:
4266             {
4267                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4268                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4269                 if (arg0_value == ag->codegen->invalid_inst_src)
4270                     return arg0_value;
4271 
4272                 if (!ag->in_c_import_scope) {
4273                     add_node_error(ag->codegen, node, buf_sprintf("C include valid only inside C import block"));
4274                     return ag->codegen->invalid_inst_src;
4275                 }
4276 
4277                 Stage1ZirInst *c_include = ir_build_c_include(ag, scope, node, arg0_value);
4278                 return ir_lval_wrap(ag, scope, c_include, lval, result_loc);
4279             }
4280         case BuiltinFnIdCDefine:
4281             {
4282                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4283                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4284                 if (arg0_value == ag->codegen->invalid_inst_src)
4285                     return arg0_value;
4286 
4287                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4288                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4289                 if (arg1_value == ag->codegen->invalid_inst_src)
4290                     return arg1_value;
4291 
4292                 if (!ag->in_c_import_scope) {
4293                     add_node_error(ag->codegen, node, buf_sprintf("C define valid only inside C import block"));
4294                     return ag->codegen->invalid_inst_src;
4295                 }
4296 
4297                 Stage1ZirInst *c_define = ir_build_c_define(ag, scope, node, arg0_value, arg1_value);
4298                 return ir_lval_wrap(ag, scope, c_define, lval, result_loc);
4299             }
4300         case BuiltinFnIdCUndef:
4301             {
4302                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4303                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4304                 if (arg0_value == ag->codegen->invalid_inst_src)
4305                     return arg0_value;
4306 
4307                 if (!ag->in_c_import_scope) {
4308                     add_node_error(ag->codegen, node, buf_sprintf("C undef valid only inside C import block"));
4309                     return ag->codegen->invalid_inst_src;
4310                 }
4311 
4312                 Stage1ZirInst *c_undef = ir_build_c_undef(ag, scope, node, arg0_value);
4313                 return ir_lval_wrap(ag, scope, c_undef, lval, result_loc);
4314             }
4315         case BuiltinFnIdCompileErr:
4316             {
4317                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4318                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4319                 if (arg0_value == ag->codegen->invalid_inst_src)
4320                     return arg0_value;
4321 
4322                 Stage1ZirInst *compile_err = ir_build_compile_err(ag, scope, node, arg0_value);
4323                 return ir_lval_wrap(ag, scope, compile_err, lval, result_loc);
4324             }
4325         case BuiltinFnIdCompileLog:
4326             {
4327                 Stage1ZirInst **args = heap::c_allocator.allocate<Stage1ZirInst*>(actual_param_count);
4328 
4329                 for (size_t i = 0; i < actual_param_count; i += 1) {
4330                     AstNode *arg_node = node->data.fn_call_expr.params.at(i);
4331                     args[i] = astgen_node(ag, arg_node, scope);
4332                     if (args[i] == ag->codegen->invalid_inst_src)
4333                         return ag->codegen->invalid_inst_src;
4334                 }
4335 
4336                 Stage1ZirInst *compile_log = ir_build_compile_log(ag, scope, node, actual_param_count, args);
4337                 return ir_lval_wrap(ag, scope, compile_log, lval, result_loc);
4338             }
4339         case BuiltinFnIdErrName:
4340             {
4341                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4342                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4343                 if (arg0_value == ag->codegen->invalid_inst_src)
4344                     return arg0_value;
4345 
4346                 Stage1ZirInst *err_name = ir_build_err_name(ag, scope, node, arg0_value);
4347                 return ir_lval_wrap(ag, scope, err_name, lval, result_loc);
4348             }
4349         case BuiltinFnIdEmbedFile:
4350             {
4351                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4352                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4353                 if (arg0_value == ag->codegen->invalid_inst_src)
4354                     return arg0_value;
4355 
4356                 Stage1ZirInst *embed_file = ir_build_embed_file(ag, scope, node, arg0_value);
4357                 return ir_lval_wrap(ag, scope, embed_file, lval, result_loc);
4358             }
4359         case BuiltinFnIdCmpxchgWeak:
4360         case BuiltinFnIdCmpxchgStrong:
4361             {
4362                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4363                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4364                 if (arg0_value == ag->codegen->invalid_inst_src)
4365                     return arg0_value;
4366 
4367                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4368                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4369                 if (arg1_value == ag->codegen->invalid_inst_src)
4370                     return arg1_value;
4371 
4372                 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4373                 Stage1ZirInst *arg2_value = astgen_node(ag, arg2_node, scope);
4374                 if (arg2_value == ag->codegen->invalid_inst_src)
4375                     return arg2_value;
4376 
4377                 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
4378                 Stage1ZirInst *arg3_value = astgen_node(ag, arg3_node, scope);
4379                 if (arg3_value == ag->codegen->invalid_inst_src)
4380                     return arg3_value;
4381 
4382                 AstNode *arg4_node = node->data.fn_call_expr.params.at(4);
4383                 Stage1ZirInst *arg4_value = astgen_node(ag, arg4_node, scope);
4384                 if (arg4_value == ag->codegen->invalid_inst_src)
4385                     return arg4_value;
4386 
4387                 AstNode *arg5_node = node->data.fn_call_expr.params.at(5);
4388                 Stage1ZirInst *arg5_value = astgen_node(ag, arg5_node, scope);
4389                 if (arg5_value == ag->codegen->invalid_inst_src)
4390                     return arg5_value;
4391 
4392                 Stage1ZirInst *cmpxchg = ir_build_cmpxchg_src(ag, scope, node, arg0_value, arg1_value,
4393                     arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak),
4394                     result_loc);
4395                 return ir_lval_wrap(ag, scope, cmpxchg, lval, result_loc);
4396             }
4397         case BuiltinFnIdFence:
4398             {
4399                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4400                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4401                 if (arg0_value == ag->codegen->invalid_inst_src)
4402                     return arg0_value;
4403 
4404                 Stage1ZirInst *fence = ir_build_fence(ag, scope, node, arg0_value);
4405                 return ir_lval_wrap(ag, scope, fence, lval, result_loc);
4406             }
4407         case BuiltinFnIdReduce:
4408             {
4409                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4410                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4411                 if (arg0_value == ag->codegen->invalid_inst_src)
4412                     return arg0_value;
4413 
4414                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4415                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4416                 if (arg1_value == ag->codegen->invalid_inst_src)
4417                     return arg1_value;
4418 
4419                 Stage1ZirInst *reduce = ir_build_reduce(ag, scope, node, arg0_value, arg1_value);
4420                 return ir_lval_wrap(ag, scope, reduce, lval, result_loc);
4421             }
4422         case BuiltinFnIdDivExact:
4423             {
4424                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4425                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4426                 if (arg0_value == ag->codegen->invalid_inst_src)
4427                     return arg0_value;
4428 
4429                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4430                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4431                 if (arg1_value == ag->codegen->invalid_inst_src)
4432                     return arg1_value;
4433 
4434                 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true);
4435                 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4436             }
4437         case BuiltinFnIdDivTrunc:
4438             {
4439                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4440                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4441                 if (arg0_value == ag->codegen->invalid_inst_src)
4442                     return arg0_value;
4443 
4444                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4445                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4446                 if (arg1_value == ag->codegen->invalid_inst_src)
4447                     return arg1_value;
4448 
4449                 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true);
4450                 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4451             }
4452         case BuiltinFnIdDivFloor:
4453             {
4454                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4455                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4456                 if (arg0_value == ag->codegen->invalid_inst_src)
4457                     return arg0_value;
4458 
4459                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4460                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4461                 if (arg1_value == ag->codegen->invalid_inst_src)
4462                     return arg1_value;
4463 
4464                 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true);
4465                 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4466             }
4467         case BuiltinFnIdRem:
4468             {
4469                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4470                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4471                 if (arg0_value == ag->codegen->invalid_inst_src)
4472                     return arg0_value;
4473 
4474                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4475                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4476                 if (arg1_value == ag->codegen->invalid_inst_src)
4477                     return arg1_value;
4478 
4479                 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true);
4480                 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4481             }
4482         case BuiltinFnIdMod:
4483             {
4484                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4485                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4486                 if (arg0_value == ag->codegen->invalid_inst_src)
4487                     return arg0_value;
4488 
4489                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4490                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4491                 if (arg1_value == ag->codegen->invalid_inst_src)
4492                     return arg1_value;
4493 
4494                 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true);
4495                 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4496             }
4497         case BuiltinFnIdSqrt:
4498         case BuiltinFnIdSin:
4499         case BuiltinFnIdCos:
4500         case BuiltinFnIdExp:
4501         case BuiltinFnIdExp2:
4502         case BuiltinFnIdLog:
4503         case BuiltinFnIdLog2:
4504         case BuiltinFnIdLog10:
4505         case BuiltinFnIdFabs:
4506         case BuiltinFnIdFloor:
4507         case BuiltinFnIdCeil:
4508         case BuiltinFnIdTrunc:
4509         case BuiltinFnIdNearbyInt:
4510         case BuiltinFnIdRound:
4511             {
4512                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4513                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4514                 if (arg0_value == ag->codegen->invalid_inst_src)
4515                     return arg0_value;
4516 
4517                 Stage1ZirInst *inst = ir_build_float_op_src(ag, scope, node, arg0_value, builtin_fn->id);
4518                 return ir_lval_wrap(ag, scope, inst, lval, result_loc);
4519             }
4520         case BuiltinFnIdTruncate:
4521             {
4522                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4523                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4524                 if (arg0_value == ag->codegen->invalid_inst_src)
4525                     return arg0_value;
4526 
4527                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4528                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4529                 if (arg1_value == ag->codegen->invalid_inst_src)
4530                     return arg1_value;
4531 
4532                 Stage1ZirInst *truncate = ir_build_truncate(ag, scope, node, arg0_value, arg1_value);
4533                 return ir_lval_wrap(ag, scope, truncate, lval, result_loc);
4534             }
4535         case BuiltinFnIdIntCast:
4536             {
4537                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4538                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4539                 if (arg0_value == ag->codegen->invalid_inst_src)
4540                     return arg0_value;
4541 
4542                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4543                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4544                 if (arg1_value == ag->codegen->invalid_inst_src)
4545                     return arg1_value;
4546 
4547                 Stage1ZirInst *result = ir_build_int_cast(ag, scope, node, arg0_value, arg1_value);
4548                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4549             }
4550         case BuiltinFnIdFloatCast:
4551             {
4552                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4553                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4554                 if (arg0_value == ag->codegen->invalid_inst_src)
4555                     return arg0_value;
4556 
4557                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4558                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4559                 if (arg1_value == ag->codegen->invalid_inst_src)
4560                     return arg1_value;
4561 
4562                 Stage1ZirInst *result = ir_build_float_cast(ag, scope, node, arg0_value, arg1_value);
4563                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4564             }
4565         case BuiltinFnIdErrSetCast:
4566             {
4567                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4568                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4569                 if (arg0_value == ag->codegen->invalid_inst_src)
4570                     return arg0_value;
4571 
4572                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4573                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4574                 if (arg1_value == ag->codegen->invalid_inst_src)
4575                     return arg1_value;
4576 
4577                 Stage1ZirInst *result = ir_build_err_set_cast(ag, scope, node, arg0_value, arg1_value);
4578                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4579             }
4580         case BuiltinFnIdIntToFloat:
4581             {
4582                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4583                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4584                 if (arg0_value == ag->codegen->invalid_inst_src)
4585                     return arg0_value;
4586 
4587                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4588                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4589                 if (arg1_value == ag->codegen->invalid_inst_src)
4590                     return arg1_value;
4591 
4592                 Stage1ZirInst *result = ir_build_int_to_float(ag, scope, node, arg0_value, arg1_value);
4593                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4594             }
4595         case BuiltinFnIdFloatToInt:
4596             {
4597                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4598                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4599                 if (arg0_value == ag->codegen->invalid_inst_src)
4600                     return arg0_value;
4601 
4602                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4603                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4604                 if (arg1_value == ag->codegen->invalid_inst_src)
4605                     return arg1_value;
4606 
4607                 Stage1ZirInst *result = ir_build_float_to_int(ag, scope, node, arg0_value, arg1_value);
4608                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4609             }
4610         case BuiltinFnIdErrToInt:
4611             {
4612                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4613                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4614                 if (arg0_value == ag->codegen->invalid_inst_src)
4615                     return arg0_value;
4616 
4617                 Stage1ZirInst *result = ir_build_err_to_int_src(ag, scope, node, arg0_value);
4618                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4619             }
4620         case BuiltinFnIdIntToErr:
4621             {
4622                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4623                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4624                 if (arg0_value == ag->codegen->invalid_inst_src)
4625                     return arg0_value;
4626 
4627                 Stage1ZirInst *result = ir_build_int_to_err_src(ag, scope, node, arg0_value);
4628                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4629             }
4630         case BuiltinFnIdBoolToInt:
4631             {
4632                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4633                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4634                 if (arg0_value == ag->codegen->invalid_inst_src)
4635                     return arg0_value;
4636 
4637                 Stage1ZirInst *result = ir_build_bool_to_int(ag, scope, node, arg0_value);
4638                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
4639             }
4640         case BuiltinFnIdVectorType:
4641             {
4642                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4643                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4644                 if (arg0_value == ag->codegen->invalid_inst_src)
4645                     return arg0_value;
4646 
4647                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4648                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4649                 if (arg1_value == ag->codegen->invalid_inst_src)
4650                     return arg1_value;
4651 
4652                 Stage1ZirInst *vector_type = ir_build_vector_type(ag, scope, node, arg0_value, arg1_value);
4653                 return ir_lval_wrap(ag, scope, vector_type, lval, result_loc);
4654             }
4655         case BuiltinFnIdShuffle:
4656             {
4657                 // Used for the type expr and the mask expr
4658                 Scope *comptime_scope = create_comptime_scope(ag->codegen, node, scope);
4659 
4660                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4661                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, comptime_scope);
4662                 if (arg0_value == ag->codegen->invalid_inst_src)
4663                     return arg0_value;
4664 
4665                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4666                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4667                 if (arg1_value == ag->codegen->invalid_inst_src)
4668                     return arg1_value;
4669 
4670                 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4671                 Stage1ZirInst *arg2_value = astgen_node(ag, arg2_node, scope);
4672                 if (arg2_value == ag->codegen->invalid_inst_src)
4673                     return arg2_value;
4674 
4675                 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
4676                 Stage1ZirInst *arg3_value = astgen_node(ag, arg3_node, comptime_scope);
4677                 if (arg3_value == ag->codegen->invalid_inst_src)
4678                     return arg3_value;
4679 
4680                 Stage1ZirInst *shuffle_vector = ir_build_shuffle_vector(ag, scope, node,
4681                     arg0_value, arg1_value, arg2_value, arg3_value);
4682                 return ir_lval_wrap(ag, scope, shuffle_vector, lval, result_loc);
4683             }
4684         case BuiltinFnIdSelect:
4685             {
4686                 // Used for the type expr
4687                 Scope *comptime_scope = create_comptime_scope(ag->codegen, node, scope);
4688 
4689                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4690                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, comptime_scope);
4691                 if (arg0_value == ag->codegen->invalid_inst_src)
4692                     return arg0_value;
4693 
4694                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4695                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4696                 if (arg1_value == ag->codegen->invalid_inst_src)
4697                     return arg1_value;
4698 
4699                 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4700                 Stage1ZirInst *arg2_value = astgen_node(ag, arg2_node, scope);
4701                 if (arg2_value == ag->codegen->invalid_inst_src)
4702                     return arg2_value;
4703 
4704                 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
4705                 Stage1ZirInst *arg3_value = astgen_node(ag, arg3_node, scope);
4706                 if (arg3_value == ag->codegen->invalid_inst_src)
4707                     return arg3_value;
4708 
4709                 Stage1ZirInst *select = ir_build_select(ag, scope, node,
4710                     arg0_value, arg1_value, arg2_value, arg3_value);
4711                 return ir_lval_wrap(ag, scope, select, lval, result_loc);
4712             }
4713         case BuiltinFnIdSplat:
4714             {
4715                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4716                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4717                 if (arg0_value == ag->codegen->invalid_inst_src)
4718                     return arg0_value;
4719 
4720                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4721                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4722                 if (arg1_value == ag->codegen->invalid_inst_src)
4723                     return arg1_value;
4724 
4725                 Stage1ZirInst *splat = ir_build_splat_src(ag, scope, node,
4726                     arg0_value, arg1_value);
4727                 return ir_lval_wrap(ag, scope, splat, lval, result_loc);
4728             }
4729         case BuiltinFnIdMaximum:
4730             {
4731                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4732                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4733                 if (arg0_value == ag->codegen->invalid_inst_src)
4734                     return arg0_value;
4735 
4736                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4737                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4738                 if (arg1_value == ag->codegen->invalid_inst_src)
4739                     return arg1_value;
4740 
4741                 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpMaximum, arg0_value, arg1_value, true);
4742                 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4743             }
4744         case BuiltinFnIdMemcpy:
4745             {
4746                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4747                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4748                 if (arg0_value == ag->codegen->invalid_inst_src)
4749                     return arg0_value;
4750 
4751                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4752                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4753                 if (arg1_value == ag->codegen->invalid_inst_src)
4754                     return arg1_value;
4755 
4756                 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4757                 Stage1ZirInst *arg2_value = astgen_node(ag, arg2_node, scope);
4758                 if (arg2_value == ag->codegen->invalid_inst_src)
4759                     return arg2_value;
4760 
4761                 Stage1ZirInst *ir_memcpy = ir_build_memcpy_src(ag, scope, node, arg0_value, arg1_value, arg2_value);
4762                 return ir_lval_wrap(ag, scope, ir_memcpy, lval, result_loc);
4763             }
4764         case BuiltinFnIdMemset:
4765             {
4766                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4767                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4768                 if (arg0_value == ag->codegen->invalid_inst_src)
4769                     return arg0_value;
4770 
4771                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4772                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4773                 if (arg1_value == ag->codegen->invalid_inst_src)
4774                     return arg1_value;
4775 
4776                 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
4777                 Stage1ZirInst *arg2_value = astgen_node(ag, arg2_node, scope);
4778                 if (arg2_value == ag->codegen->invalid_inst_src)
4779                     return arg2_value;
4780 
4781                 Stage1ZirInst *ir_memset = ir_build_memset_src(ag, scope, node, arg0_value, arg1_value, arg2_value);
4782                 return ir_lval_wrap(ag, scope, ir_memset, lval, result_loc);
4783             }
4784         case BuiltinFnIdMinimum:
4785             {
4786                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4787                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4788                 if (arg0_value == ag->codegen->invalid_inst_src)
4789                     return arg0_value;
4790 
4791                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4792                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4793                 if (arg1_value == ag->codegen->invalid_inst_src)
4794                     return arg1_value;
4795 
4796                 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpMinimum, arg0_value, arg1_value, true);
4797                 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
4798             }
4799         case BuiltinFnIdWasmMemorySize:
4800             {
4801                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4802                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4803                 if (arg0_value == ag->codegen->invalid_inst_src)
4804                     return arg0_value;
4805 
4806                 Stage1ZirInst *ir_wasm_memory_size = ir_build_wasm_memory_size_src(ag, scope, node, arg0_value);
4807                 return ir_lval_wrap(ag, scope, ir_wasm_memory_size, lval, result_loc);
4808             }
4809         case BuiltinFnIdWasmMemoryGrow:
4810             {
4811                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4812                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4813                 if (arg0_value == ag->codegen->invalid_inst_src)
4814                     return arg0_value;
4815 
4816                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4817                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4818                 if (arg1_value == ag->codegen->invalid_inst_src)
4819                     return arg1_value;
4820 
4821                 Stage1ZirInst *ir_wasm_memory_grow = ir_build_wasm_memory_grow_src(ag, scope, node, arg0_value, arg1_value);
4822                 return ir_lval_wrap(ag, scope, ir_wasm_memory_grow, lval, result_loc);
4823             }
4824         case BuiltinFnIdField:
4825             {
4826                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4827                 Stage1ZirInst *arg0_value = astgen_node_extra(ag, arg0_node, scope, LValPtr, nullptr);
4828                 if (arg0_value == ag->codegen->invalid_inst_src)
4829                     return arg0_value;
4830 
4831                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4832                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4833                 if (arg1_value == ag->codegen->invalid_inst_src)
4834                     return arg1_value;
4835 
4836                 Stage1ZirInst *ptr_instruction = ir_build_field_ptr_instruction(ag, scope, node,
4837                         arg0_value, arg1_value, false);
4838 
4839                 if (lval == LValPtr || lval == LValAssign)
4840                     return ptr_instruction;
4841 
4842                 Stage1ZirInst *load_ptr = ir_build_load_ptr(ag, scope, node, ptr_instruction);
4843                 return ir_expr_wrap(ag, scope, load_ptr, result_loc);
4844             }
4845         case BuiltinFnIdHasField:
4846             {
4847                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4848                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4849                 if (arg0_value == ag->codegen->invalid_inst_src)
4850                     return arg0_value;
4851 
4852                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4853                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4854                 if (arg1_value == ag->codegen->invalid_inst_src)
4855                     return arg1_value;
4856 
4857                 Stage1ZirInst *type_info = ir_build_has_field(ag, scope, node, arg0_value, arg1_value);
4858                 return ir_lval_wrap(ag, scope, type_info, lval, result_loc);
4859             }
4860         case BuiltinFnIdTypeInfo:
4861             {
4862                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4863                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4864                 if (arg0_value == ag->codegen->invalid_inst_src)
4865                     return arg0_value;
4866 
4867                 Stage1ZirInst *type_info = ir_build_type_info(ag, scope, node, arg0_value);
4868                 return ir_lval_wrap(ag, scope, type_info, lval, result_loc);
4869             }
4870         case BuiltinFnIdType:
4871             {
4872                 AstNode *arg_node = node->data.fn_call_expr.params.at(0);
4873                 Stage1ZirInst *arg = astgen_node(ag, arg_node, scope);
4874                 if (arg == ag->codegen->invalid_inst_src)
4875                     return arg;
4876 
4877                 Stage1ZirInst *type = ir_build_type(ag, scope, node, arg);
4878                 return ir_lval_wrap(ag, scope, type, lval, result_loc);
4879             }
4880         case BuiltinFnIdBreakpoint:
4881             return ir_lval_wrap(ag, scope, ir_build_breakpoint(ag, scope, node), lval, result_loc);
4882         case BuiltinFnIdReturnAddress:
4883             return ir_lval_wrap(ag, scope, ir_build_return_address_src(ag, scope, node), lval, result_loc);
4884         case BuiltinFnIdFrameAddress:
4885             return ir_lval_wrap(ag, scope, ir_build_frame_address_src(ag, scope, node), lval, result_loc);
4886         case BuiltinFnIdFrameHandle:
4887             if (ag->fn == nullptr) {
4888                 add_node_error(ag->codegen, node,
4889                         buf_sprintf("@frame() called outside of function definition"));
4890                 return ag->codegen->invalid_inst_src;
4891             }
4892             return ir_lval_wrap(ag, scope, ir_build_handle_src(ag, scope, node), lval, result_loc);
4893         case BuiltinFnIdFrameType: {
4894             AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4895             Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4896             if (arg0_value == ag->codegen->invalid_inst_src)
4897                 return arg0_value;
4898 
4899             Stage1ZirInst *frame_type = ir_build_frame_type(ag, scope, node, arg0_value);
4900             return ir_lval_wrap(ag, scope, frame_type, lval, result_loc);
4901         }
4902         case BuiltinFnIdFrameSize: {
4903             AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4904             Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4905             if (arg0_value == ag->codegen->invalid_inst_src)
4906                 return arg0_value;
4907 
4908             Stage1ZirInst *frame_size = ir_build_frame_size_src(ag, scope, node, arg0_value);
4909             return ir_lval_wrap(ag, scope, frame_size, lval, result_loc);
4910         }
4911         case BuiltinFnIdAlignOf:
4912             {
4913                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4914                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4915                 if (arg0_value == ag->codegen->invalid_inst_src)
4916                     return arg0_value;
4917 
4918                 Stage1ZirInst *align_of = ir_build_align_of(ag, scope, node, arg0_value);
4919                 return ir_lval_wrap(ag, scope, align_of, lval, result_loc);
4920             }
4921         case BuiltinFnIdAddWithOverflow:
4922             return ir_lval_wrap(ag, scope, astgen_overflow_op(ag, scope, node, IrOverflowOpAdd), lval, result_loc);
4923         case BuiltinFnIdSubWithOverflow:
4924             return ir_lval_wrap(ag, scope, astgen_overflow_op(ag, scope, node, IrOverflowOpSub), lval, result_loc);
4925         case BuiltinFnIdMulWithOverflow:
4926             return ir_lval_wrap(ag, scope, astgen_overflow_op(ag, scope, node, IrOverflowOpMul), lval, result_loc);
4927         case BuiltinFnIdShlWithOverflow:
4928             return ir_lval_wrap(ag, scope, astgen_overflow_op(ag, scope, node, IrOverflowOpShl), lval, result_loc);
4929         case BuiltinFnIdMulAdd:
4930             return ir_lval_wrap(ag, scope, astgen_mul_add(ag, scope, node), lval, result_loc);
4931         case BuiltinFnIdTypeName:
4932             {
4933                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4934                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4935                 if (arg0_value == ag->codegen->invalid_inst_src)
4936                     return arg0_value;
4937 
4938                 Stage1ZirInst *type_name = ir_build_type_name(ag, scope, node, arg0_value);
4939                 return ir_lval_wrap(ag, scope, type_name, lval, result_loc);
4940             }
4941         case BuiltinFnIdPanic:
4942             {
4943                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4944                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4945                 if (arg0_value == ag->codegen->invalid_inst_src)
4946                     return arg0_value;
4947 
4948                 Stage1ZirInst *panic = ir_build_panic_src(ag, scope, node, arg0_value);
4949                 return ir_lval_wrap(ag, scope, panic, lval, result_loc);
4950             }
4951         case BuiltinFnIdPtrCast:
4952             {
4953                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
4954                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
4955                 if (arg0_value == ag->codegen->invalid_inst_src)
4956                     return arg0_value;
4957 
4958                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4959                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
4960                 if (arg1_value == ag->codegen->invalid_inst_src)
4961                     return arg1_value;
4962 
4963                 Stage1ZirInst *ptr_cast = ir_build_ptr_cast_src(ag, scope, node, arg0_value, arg1_value, true);
4964                 return ir_lval_wrap(ag, scope, ptr_cast, lval, result_loc);
4965             }
4966         case BuiltinFnIdBitCast:
4967             {
4968                 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0);
4969                 Stage1ZirInst *dest_type = astgen_node(ag, dest_type_node, scope);
4970                 if (dest_type == ag->codegen->invalid_inst_src)
4971                     return dest_type;
4972 
4973                 ResultLocBitCast *result_loc_bit_cast = heap::c_allocator.create<ResultLocBitCast>();
4974                 result_loc_bit_cast->base.id = ResultLocIdBitCast;
4975                 result_loc_bit_cast->base.source_instruction = dest_type;
4976                 result_loc_bit_cast->base.allow_write_through_const = result_loc->allow_write_through_const;
4977                 ir_ref_instruction(dest_type, ag->current_basic_block);
4978                 result_loc_bit_cast->parent = result_loc;
4979 
4980                 ir_build_reset_result(ag, scope, node, &result_loc_bit_cast->base);
4981 
4982                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
4983                 Stage1ZirInst *arg1_value = astgen_node_extra(ag, arg1_node, scope, LValNone,
4984                         &result_loc_bit_cast->base);
4985                 if (arg1_value == ag->codegen->invalid_inst_src)
4986                     return arg1_value;
4987 
4988                 Stage1ZirInst *bitcast = ir_build_bit_cast_src(ag, scope, arg1_node, arg1_value, result_loc_bit_cast);
4989                 return ir_lval_wrap(ag, scope, bitcast, lval, result_loc);
4990             }
4991         case BuiltinFnIdAs:
4992             {
4993                 AstNode *dest_type_node = node->data.fn_call_expr.params.at(0);
4994                 Stage1ZirInst *dest_type = astgen_node(ag, dest_type_node, scope);
4995                 if (dest_type == ag->codegen->invalid_inst_src)
4996                     return dest_type;
4997 
4998                 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, dest_type, result_loc);
4999 
5000                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5001                 Stage1ZirInst *arg1_value = astgen_node_extra(ag, arg1_node, scope, LValNone,
5002                         &result_loc_cast->base);
5003                 if (arg1_value == ag->codegen->invalid_inst_src)
5004                     return arg1_value;
5005 
5006                 Stage1ZirInst *result = ir_build_implicit_cast(ag, scope, node, arg1_value, result_loc_cast);
5007                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
5008             }
5009         case BuiltinFnIdIntToPtr:
5010             {
5011                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5012                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5013                 if (arg0_value == ag->codegen->invalid_inst_src)
5014                     return arg0_value;
5015 
5016                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5017                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5018                 if (arg1_value == ag->codegen->invalid_inst_src)
5019                     return arg1_value;
5020 
5021                 Stage1ZirInst *int_to_ptr = ir_build_int_to_ptr_src(ag, scope, node, arg0_value, arg1_value);
5022                 return ir_lval_wrap(ag, scope, int_to_ptr, lval, result_loc);
5023             }
5024         case BuiltinFnIdPtrToInt:
5025             {
5026                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5027                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5028                 if (arg0_value == ag->codegen->invalid_inst_src)
5029                     return arg0_value;
5030 
5031                 Stage1ZirInst *ptr_to_int = ir_build_ptr_to_int_src(ag, scope, node, arg0_value);
5032                 return ir_lval_wrap(ag, scope, ptr_to_int, lval, result_loc);
5033             }
5034         case BuiltinFnIdTagName:
5035             {
5036                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5037                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5038                 if (arg0_value == ag->codegen->invalid_inst_src)
5039                     return arg0_value;
5040 
5041                 Stage1ZirInst *tag_name = ir_build_tag_name_src(ag, scope, node, arg0_value);
5042                 return ir_lval_wrap(ag, scope, tag_name, lval, result_loc);
5043             }
5044         case BuiltinFnIdFieldParentPtr:
5045             {
5046                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5047                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5048                 if (arg0_value == ag->codegen->invalid_inst_src)
5049                     return arg0_value;
5050 
5051                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5052                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5053                 if (arg1_value == ag->codegen->invalid_inst_src)
5054                     return arg1_value;
5055 
5056                 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
5057                 Stage1ZirInst *arg2_value = astgen_node(ag, arg2_node, scope);
5058                 if (arg2_value == ag->codegen->invalid_inst_src)
5059                     return arg2_value;
5060 
5061                 Stage1ZirInst *field_parent_ptr = ir_build_field_parent_ptr_src(ag, scope, node,
5062                         arg0_value, arg1_value, arg2_value);
5063                 return ir_lval_wrap(ag, scope, field_parent_ptr, lval, result_loc);
5064             }
5065         case BuiltinFnIdOffsetOf:
5066             {
5067                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5068                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5069                 if (arg0_value == ag->codegen->invalid_inst_src)
5070                     return arg0_value;
5071 
5072                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5073                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5074                 if (arg1_value == ag->codegen->invalid_inst_src)
5075                     return arg1_value;
5076 
5077                 Stage1ZirInst *offset_of = ir_build_offset_of(ag, scope, node, arg0_value, arg1_value);
5078                 return ir_lval_wrap(ag, scope, offset_of, lval, result_loc);
5079             }
5080         case BuiltinFnIdBitOffsetOf:
5081             {
5082                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5083                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5084                 if (arg0_value == ag->codegen->invalid_inst_src)
5085                     return arg0_value;
5086 
5087                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5088                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5089                 if (arg1_value == ag->codegen->invalid_inst_src)
5090                     return arg1_value;
5091 
5092                 Stage1ZirInst *offset_of = ir_build_bit_offset_of(ag, scope, node, arg0_value, arg1_value);
5093                 return ir_lval_wrap(ag, scope, offset_of, lval, result_loc);
5094             }
5095         case BuiltinFnIdCall: {
5096             // Cast the options parameter to the options type
5097             ZigType *options_type = get_builtin_type(ag->codegen, "CallOptions");
5098             Stage1ZirInst *options_type_inst = ir_build_const_type(ag, scope, node, options_type);
5099             ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, options_type_inst, no_result_loc());
5100 
5101             AstNode *options_node = node->data.fn_call_expr.params.at(0);
5102             Stage1ZirInst *options_inner = astgen_node_extra(ag, options_node, scope,
5103                     LValNone, &result_loc_cast->base);
5104             if (options_inner == ag->codegen->invalid_inst_src)
5105                 return options_inner;
5106             Stage1ZirInst *options = ir_build_implicit_cast(ag, scope, options_node, options_inner, result_loc_cast);
5107 
5108             AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1);
5109             AstNode *args_node = node->data.fn_call_expr.params.at(2);
5110             if (args_node->type == NodeTypeContainerInitExpr) {
5111                 if (args_node->data.container_init_expr.kind == ContainerInitKindArray ||
5112                     args_node->data.container_init_expr.entries.length == 0)
5113                 {
5114                     return astgen_fn_call_with_args(ag, scope, node,
5115                             fn_ref_node, CallModifierNone, options,
5116                             args_node->data.container_init_expr.entries.items,
5117                             args_node->data.container_init_expr.entries.length,
5118                             lval, result_loc);
5119                 } else {
5120                     exec_add_error_node(ag->codegen, ag->exec, args_node,
5121                             buf_sprintf("TODO: @call with anon struct literal"));
5122                     return ag->codegen->invalid_inst_src;
5123                 }
5124             } else {
5125                 Stage1ZirInst *fn_ref = astgen_node(ag, fn_ref_node, scope);
5126                 if (fn_ref == ag->codegen->invalid_inst_src)
5127                     return fn_ref;
5128 
5129                 Stage1ZirInst *args = astgen_node(ag, args_node, scope);
5130                 if (args == ag->codegen->invalid_inst_src)
5131                     return args;
5132 
5133                 Stage1ZirInst *call = ir_build_call_extra(ag, scope, node, options, fn_ref, args, result_loc);
5134                 return ir_lval_wrap(ag, scope, call, lval, result_loc);
5135             }
5136         }
5137         case BuiltinFnIdAsyncCall:
5138             return astgen_async_call(ag, scope, nullptr, node, lval, result_loc);
5139         case BuiltinFnIdShlExact:
5140             {
5141                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5142                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5143                 if (arg0_value == ag->codegen->invalid_inst_src)
5144                     return arg0_value;
5145 
5146                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5147                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5148                 if (arg1_value == ag->codegen->invalid_inst_src)
5149                     return arg1_value;
5150 
5151                 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true);
5152                 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
5153             }
5154         case BuiltinFnIdShrExact:
5155             {
5156                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5157                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5158                 if (arg0_value == ag->codegen->invalid_inst_src)
5159                     return arg0_value;
5160 
5161                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5162                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5163                 if (arg1_value == ag->codegen->invalid_inst_src)
5164                     return arg1_value;
5165 
5166                 Stage1ZirInst *bin_op = ir_build_bin_op(ag, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true);
5167                 return ir_lval_wrap(ag, scope, bin_op, lval, result_loc);
5168             }
5169         case BuiltinFnIdSetEvalBranchQuota:
5170             {
5171                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5172                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5173                 if (arg0_value == ag->codegen->invalid_inst_src)
5174                     return arg0_value;
5175 
5176                 Stage1ZirInst *set_eval_branch_quota = ir_build_set_eval_branch_quota(ag, scope, node, arg0_value);
5177                 return ir_lval_wrap(ag, scope, set_eval_branch_quota, lval, result_loc);
5178             }
5179         case BuiltinFnIdAlignCast:
5180             {
5181                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5182                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5183                 if (arg0_value == ag->codegen->invalid_inst_src)
5184                     return arg0_value;
5185 
5186                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5187                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5188                 if (arg1_value == ag->codegen->invalid_inst_src)
5189                     return arg1_value;
5190 
5191                 Stage1ZirInst *align_cast = ir_build_align_cast_src(ag, scope, node, arg0_value, arg1_value);
5192                 return ir_lval_wrap(ag, scope, align_cast, lval, result_loc);
5193             }
5194         case BuiltinFnIdThis:
5195             {
5196                 Stage1ZirInst *this_inst = astgen_this(ag, scope, node);
5197                 return ir_lval_wrap(ag, scope, this_inst, lval, result_loc);
5198             }
5199         case BuiltinFnIdSetAlignStack:
5200             {
5201                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5202                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5203                 if (arg0_value == ag->codegen->invalid_inst_src)
5204                     return arg0_value;
5205 
5206                 Stage1ZirInst *set_align_stack = ir_build_set_align_stack(ag, scope, node, arg0_value);
5207                 return ir_lval_wrap(ag, scope, set_align_stack, lval, result_loc);
5208             }
5209         case BuiltinFnIdExport:
5210             {
5211                 // Cast the options parameter to the options type
5212                 ZigType *options_type = get_builtin_type(ag->codegen, "ExportOptions");
5213                 Stage1ZirInst *options_type_inst = ir_build_const_type(ag, scope, node, options_type);
5214                 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, options_type_inst, no_result_loc());
5215 
5216                 AstNode *target_node = node->data.fn_call_expr.params.at(0);
5217                 Stage1ZirInst *target_value = astgen_node(ag, target_node, scope);
5218                 if (target_value == ag->codegen->invalid_inst_src)
5219                     return target_value;
5220 
5221                 AstNode *options_node = node->data.fn_call_expr.params.at(1);
5222                 Stage1ZirInst *options_value = astgen_node_extra(ag, options_node,
5223                     scope, LValNone, &result_loc_cast->base);
5224                 if (options_value == ag->codegen->invalid_inst_src)
5225                     return options_value;
5226 
5227                 Stage1ZirInst *casted_options_value = ir_build_implicit_cast(
5228                     ag, scope, options_node, options_value, result_loc_cast);
5229 
5230                 Stage1ZirInst *ir_export = ir_build_export(ag, scope, node, target_value, casted_options_value);
5231                 return ir_lval_wrap(ag, scope, ir_export, lval, result_loc);
5232             }
5233         case BuiltinFnIdExtern:
5234             {
5235                 // Cast the options parameter to the options type
5236                 ZigType *options_type = get_builtin_type(ag->codegen, "ExternOptions");
5237                 Stage1ZirInst *options_type_inst = ir_build_const_type(ag, scope, node, options_type);
5238                 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, options_type_inst, no_result_loc());
5239 
5240                 AstNode *type_node = node->data.fn_call_expr.params.at(0);
5241                 Stage1ZirInst *type_value = astgen_node(ag, type_node, scope);
5242                 if (type_value == ag->codegen->invalid_inst_src)
5243                     return type_value;
5244 
5245                 AstNode *options_node = node->data.fn_call_expr.params.at(1);
5246                 Stage1ZirInst *options_value = astgen_node_extra(ag, options_node,
5247                     scope, LValNone, &result_loc_cast->base);
5248                 if (options_value == ag->codegen->invalid_inst_src)
5249                     return options_value;
5250 
5251                 Stage1ZirInst *casted_options_value = ir_build_implicit_cast(
5252                     ag, scope, options_node, options_value, result_loc_cast);
5253 
5254                 Stage1ZirInst *ir_extern = ir_build_extern(ag, scope, node, type_value, casted_options_value);
5255                 return ir_lval_wrap(ag, scope, ir_extern, lval, result_loc);
5256             }
5257         case BuiltinFnIdErrorReturnTrace:
5258             {
5259                 Stage1ZirInst *error_return_trace = ir_build_error_return_trace_src(ag, scope, node,
5260                         IrInstErrorReturnTraceNull);
5261                 return ir_lval_wrap(ag, scope, error_return_trace, lval, result_loc);
5262             }
5263         case BuiltinFnIdAtomicRmw:
5264             {
5265                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5266                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5267                 if (arg0_value == ag->codegen->invalid_inst_src)
5268                     return arg0_value;
5269 
5270                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5271                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5272                 if (arg1_value == ag->codegen->invalid_inst_src)
5273                     return arg1_value;
5274 
5275                 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
5276                 Stage1ZirInst *arg2_value = astgen_node(ag, arg2_node, scope);
5277                 if (arg2_value == ag->codegen->invalid_inst_src)
5278                     return arg2_value;
5279 
5280                 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
5281                 Stage1ZirInst *arg3_value = astgen_node(ag, arg3_node, scope);
5282                 if (arg3_value == ag->codegen->invalid_inst_src)
5283                     return arg3_value;
5284 
5285                 AstNode *arg4_node = node->data.fn_call_expr.params.at(4);
5286                 Stage1ZirInst *arg4_value = astgen_node(ag, arg4_node, scope);
5287                 if (arg4_value == ag->codegen->invalid_inst_src)
5288                     return arg4_value;
5289 
5290                 Stage1ZirInst *inst = ir_build_atomic_rmw_src(ag, scope, node,
5291                         arg0_value, arg1_value, arg2_value, arg3_value, arg4_value);
5292                 return ir_lval_wrap(ag, scope, inst, lval, result_loc);
5293             }
5294         case BuiltinFnIdAtomicLoad:
5295             {
5296                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5297                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5298                 if (arg0_value == ag->codegen->invalid_inst_src)
5299                     return arg0_value;
5300 
5301                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5302                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5303                 if (arg1_value == ag->codegen->invalid_inst_src)
5304                     return arg1_value;
5305 
5306                 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
5307                 Stage1ZirInst *arg2_value = astgen_node(ag, arg2_node, scope);
5308                 if (arg2_value == ag->codegen->invalid_inst_src)
5309                     return arg2_value;
5310 
5311                 Stage1ZirInst *inst = ir_build_atomic_load_src(ag, scope, node, arg0_value, arg1_value, arg2_value);
5312                 return ir_lval_wrap(ag, scope, inst, lval, result_loc);
5313             }
5314         case BuiltinFnIdAtomicStore:
5315             {
5316                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5317                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5318                 if (arg0_value == ag->codegen->invalid_inst_src)
5319                     return arg0_value;
5320 
5321                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5322                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5323                 if (arg1_value == ag->codegen->invalid_inst_src)
5324                     return arg1_value;
5325 
5326                 AstNode *arg2_node = node->data.fn_call_expr.params.at(2);
5327                 Stage1ZirInst *arg2_value = astgen_node(ag, arg2_node, scope);
5328                 if (arg2_value == ag->codegen->invalid_inst_src)
5329                     return arg2_value;
5330 
5331                 AstNode *arg3_node = node->data.fn_call_expr.params.at(3);
5332                 Stage1ZirInst *arg3_value = astgen_node(ag, arg3_node, scope);
5333                 if (arg3_value == ag->codegen->invalid_inst_src)
5334                     return arg3_value;
5335 
5336                 Stage1ZirInst *inst = ir_build_atomic_store_src(ag, scope, node, arg0_value, arg1_value,
5337                         arg2_value, arg3_value);
5338                 return ir_lval_wrap(ag, scope, inst, lval, result_loc);
5339             }
5340         case BuiltinFnIdIntToEnum:
5341             {
5342                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5343                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5344                 if (arg0_value == ag->codegen->invalid_inst_src)
5345                     return arg0_value;
5346 
5347                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5348                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5349                 if (arg1_value == ag->codegen->invalid_inst_src)
5350                     return arg1_value;
5351 
5352                 Stage1ZirInst *result = ir_build_int_to_enum_src(ag, scope, node, arg0_value, arg1_value);
5353                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
5354             }
5355         case BuiltinFnIdEnumToInt:
5356             {
5357                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5358                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5359                 if (arg0_value == ag->codegen->invalid_inst_src)
5360                     return arg0_value;
5361 
5362                 Stage1ZirInst *result = ir_build_enum_to_int(ag, scope, node, arg0_value);
5363                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
5364             }
5365         case BuiltinFnIdCtz:
5366         case BuiltinFnIdPopCount:
5367         case BuiltinFnIdClz:
5368         case BuiltinFnIdBswap:
5369         case BuiltinFnIdBitReverse:
5370             {
5371                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5372                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5373                 if (arg0_value == ag->codegen->invalid_inst_src)
5374                     return arg0_value;
5375 
5376                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5377                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5378                 if (arg1_value == ag->codegen->invalid_inst_src)
5379                     return arg1_value;
5380 
5381                 Stage1ZirInst *result;
5382                 switch (builtin_fn->id) {
5383                 case BuiltinFnIdCtz:
5384                     result = ir_build_ctz(ag, scope, node, arg0_value, arg1_value);
5385                     break;
5386                 case BuiltinFnIdPopCount:
5387                     result = ir_build_pop_count(ag, scope, node, arg0_value, arg1_value);
5388                     break;
5389                 case BuiltinFnIdClz:
5390                     result = ir_build_clz(ag, scope, node, arg0_value, arg1_value);
5391                     break;
5392                 case BuiltinFnIdBswap:
5393                     result = ir_build_bswap(ag, scope, node, arg0_value, arg1_value);
5394                     break;
5395                 case BuiltinFnIdBitReverse:
5396                     result = ir_build_bit_reverse(ag, scope, node, arg0_value, arg1_value);
5397                     break;
5398                 default:
5399                     zig_unreachable();
5400                 }
5401                 return ir_lval_wrap(ag, scope, result, lval, result_loc);
5402             }
5403         case BuiltinFnIdHasDecl:
5404             {
5405                 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
5406                 Stage1ZirInst *arg0_value = astgen_node(ag, arg0_node, scope);
5407                 if (arg0_value == ag->codegen->invalid_inst_src)
5408                     return arg0_value;
5409 
5410                 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
5411                 Stage1ZirInst *arg1_value = astgen_node(ag, arg1_node, scope);
5412                 if (arg1_value == ag->codegen->invalid_inst_src)
5413                     return arg1_value;
5414 
5415                 Stage1ZirInst *has_decl = ir_build_has_decl(ag, scope, node, arg0_value, arg1_value);
5416                 return ir_lval_wrap(ag, scope, has_decl, lval, result_loc);
5417             }
5418         case BuiltinFnIdUnionInit:
5419             {
5420                 AstNode *union_type_node = node->data.fn_call_expr.params.at(0);
5421                 Stage1ZirInst *union_type_inst = astgen_node(ag, union_type_node, scope);
5422                 if (union_type_inst == ag->codegen->invalid_inst_src)
5423                     return union_type_inst;
5424 
5425                 AstNode *name_node = node->data.fn_call_expr.params.at(1);
5426                 Stage1ZirInst *name_inst = astgen_node(ag, name_node, scope);
5427                 if (name_inst == ag->codegen->invalid_inst_src)
5428                     return name_inst;
5429 
5430                 AstNode *init_node = node->data.fn_call_expr.params.at(2);
5431 
5432                 return astgen_union_init_expr(ag, scope, node, union_type_inst, name_inst, init_node,
5433                         lval, result_loc);
5434             }
5435         case BuiltinFnIdSrc:
5436             {
5437                 Stage1ZirInst *src_inst = ir_build_src(ag, scope, node);
5438                 return ir_lval_wrap(ag, scope, src_inst, lval, result_loc);
5439             }
5440         case BuiltinFnIdPrefetch:
5441             {
5442                 ZigType *options_type = get_builtin_type(ag->codegen, "PrefetchOptions");
5443                 Stage1ZirInst *options_type_inst = ir_build_const_type(ag, scope, node, options_type);
5444                 ResultLocCast *result_loc_cast = ir_build_cast_result_loc(ag, options_type_inst, no_result_loc());
5445 
5446                 AstNode *ptr_node = node->data.fn_call_expr.params.at(0);
5447                 Stage1ZirInst *ptr_value = astgen_node(ag, ptr_node, scope);
5448                 if (ptr_value == ag->codegen->invalid_inst_src)
5449                     return ptr_value;
5450 
5451                 AstNode *options_node = node->data.fn_call_expr.params.at(1);
5452                 Stage1ZirInst *options_value = astgen_node_extra(ag, options_node,
5453                     scope, LValNone, &result_loc_cast->base);
5454                 if (options_value == ag->codegen->invalid_inst_src)
5455                     return options_value;
5456 
5457                 Stage1ZirInst *casted_options_value = ir_build_implicit_cast(
5458                     ag, scope, options_node, options_value, result_loc_cast);
5459 
5460                 Stage1ZirInst *ir_extern = ir_build_prefetch(ag, scope, node, ptr_value, casted_options_value);
5461                 return ir_lval_wrap(ag, scope, ir_extern, lval, result_loc);
5462             }
5463     }
5464     zig_unreachable();
5465 }
5466 
get_scope_nosuspend(Scope * scope)5467 static ScopeNoSuspend *get_scope_nosuspend(Scope *scope) {
5468     while (scope) {
5469         if (scope->id == ScopeIdNoSuspend)
5470             return (ScopeNoSuspend *)scope;
5471         if (scope->id == ScopeIdFnDef)
5472             return nullptr;
5473 
5474         scope = scope->parent;
5475     }
5476     return nullptr;
5477 }
5478 
astgen_fn_call(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)5479 static Stage1ZirInst *astgen_fn_call(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
5480         ResultLoc *result_loc)
5481 {
5482     assert(node->type == NodeTypeFnCallExpr);
5483 
5484     if (node->data.fn_call_expr.modifier == CallModifierBuiltin)
5485         return astgen_builtin_fn_call(ag, scope, node, lval, result_loc);
5486 
5487     bool is_nosuspend = get_scope_nosuspend(scope) != nullptr;
5488     CallModifier modifier = node->data.fn_call_expr.modifier;
5489     if (is_nosuspend && modifier != CallModifierAsync) {
5490         modifier = CallModifierNoSuspend;
5491     }
5492 
5493     AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr;
5494     return astgen_fn_call_with_args(ag, scope, node, fn_ref_node, modifier,
5495         nullptr, node->data.fn_call_expr.params.items, node->data.fn_call_expr.params.length, lval, result_loc);
5496 }
5497 
astgen_if_bool_expr(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)5498 static Stage1ZirInst *astgen_if_bool_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
5499         ResultLoc *result_loc)
5500 {
5501     assert(node->type == NodeTypeIfBoolExpr);
5502 
5503     Stage1ZirInst *condition = astgen_node(ag, node->data.if_bool_expr.condition, scope);
5504     if (condition == ag->codegen->invalid_inst_src)
5505         return ag->codegen->invalid_inst_src;
5506 
5507     Stage1ZirInst *is_comptime;
5508     if (ir_should_inline(ag->exec, scope)) {
5509         is_comptime = ir_build_const_bool(ag, scope, node, true);
5510     } else {
5511         is_comptime = ir_build_test_comptime(ag, scope, node, condition);
5512     }
5513 
5514     AstNode *then_node = node->data.if_bool_expr.then_block;
5515     AstNode *else_node = node->data.if_bool_expr.else_node;
5516 
5517     Stage1ZirBasicBlock *then_block = ir_create_basic_block(ag, scope, "Then");
5518     Stage1ZirBasicBlock *else_block = ir_create_basic_block(ag, scope, "Else");
5519     Stage1ZirBasicBlock *endif_block = ir_create_basic_block(ag, scope, "EndIf");
5520 
5521     Stage1ZirInst *cond_br_inst = ir_build_cond_br(ag, scope, node, condition,
5522             then_block, else_block, is_comptime);
5523     ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(ag, cond_br_inst, else_block, endif_block,
5524             result_loc, is_comptime);
5525 
5526     ir_set_cursor_at_end_and_append_block(ag, then_block);
5527 
5528     Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
5529     Stage1ZirInst *then_expr_result = astgen_node_extra(ag, then_node, subexpr_scope, lval,
5530             &peer_parent->peers.at(0)->base);
5531     if (then_expr_result == ag->codegen->invalid_inst_src)
5532         return ag->codegen->invalid_inst_src;
5533     Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
5534     if (!instr_is_unreachable(then_expr_result))
5535         ir_build_br(ag, scope, node, endif_block, is_comptime);
5536 
5537     ir_set_cursor_at_end_and_append_block(ag, else_block);
5538     Stage1ZirInst *else_expr_result;
5539     if (else_node) {
5540         else_expr_result = astgen_node_extra(ag, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base);
5541         if (else_expr_result == ag->codegen->invalid_inst_src)
5542             return ag->codegen->invalid_inst_src;
5543     } else {
5544         else_expr_result = ir_build_const_void(ag, scope, node);
5545         ir_build_end_expr(ag, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
5546     }
5547     Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
5548     if (!instr_is_unreachable(else_expr_result))
5549         ir_build_br(ag, scope, node, endif_block, is_comptime);
5550 
5551     ir_set_cursor_at_end_and_append_block(ag, endif_block);
5552     Stage1ZirInst **incoming_values = heap::c_allocator.allocate<Stage1ZirInst *>(2);
5553     incoming_values[0] = then_expr_result;
5554     incoming_values[1] = else_expr_result;
5555     Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
5556     incoming_blocks[0] = after_then_block;
5557     incoming_blocks[1] = after_else_block;
5558 
5559     Stage1ZirInst *phi = ir_build_phi(ag, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
5560     return ir_expr_wrap(ag, scope, phi, result_loc);
5561 }
5562 
astgen_prefix_op_id_lval(Stage1AstGen * ag,Scope * scope,AstNode * node,IrUnOp op_id,LVal lval)5563 static Stage1ZirInst *astgen_prefix_op_id_lval(Stage1AstGen *ag, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) {
5564     assert(node->type == NodeTypePrefixOpExpr);
5565     AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
5566 
5567     Stage1ZirInst *value = astgen_node_extra(ag, expr_node, scope, lval, nullptr);
5568     if (value == ag->codegen->invalid_inst_src)
5569         return value;
5570 
5571     return ir_build_un_op(ag, scope, node, op_id, value);
5572 }
5573 
astgen_prefix_op_id(Stage1AstGen * ag,Scope * scope,AstNode * node,IrUnOp op_id)5574 static Stage1ZirInst *astgen_prefix_op_id(Stage1AstGen *ag, Scope *scope, AstNode *node, IrUnOp op_id) {
5575     return astgen_prefix_op_id_lval(ag, scope, node, op_id, LValNone);
5576 }
5577 
ir_expr_wrap(Stage1AstGen * ag,Scope * scope,Stage1ZirInst * inst,ResultLoc * result_loc)5578 static Stage1ZirInst *ir_expr_wrap(Stage1AstGen *ag, Scope *scope, Stage1ZirInst *inst, ResultLoc *result_loc) {
5579     if (inst == ag->codegen->invalid_inst_src) return inst;
5580     ir_build_end_expr(ag, scope, inst->source_node, inst, result_loc);
5581     return inst;
5582 }
5583 
ir_lval_wrap(Stage1AstGen * ag,Scope * scope,Stage1ZirInst * value,LVal lval,ResultLoc * result_loc)5584 static Stage1ZirInst *ir_lval_wrap(Stage1AstGen *ag, Scope *scope, Stage1ZirInst *value, LVal lval,
5585         ResultLoc *result_loc)
5586 {
5587     // This logic must be kept in sync with
5588     // [STMT_EXPR_TEST_THING] <--- (search this token)
5589     if (value == ag->codegen->invalid_inst_src ||
5590         instr_is_unreachable(value) ||
5591         value->source_node->type == NodeTypeDefer ||
5592         value->id == Stage1ZirInstIdDeclVar)
5593     {
5594         return value;
5595     }
5596 
5597     assert(lval != LValAssign);
5598     if (lval == LValPtr) {
5599         // We needed a pointer to a value, but we got a value. So we create
5600         // an instruction which just makes a pointer of it.
5601         return ir_build_ref_src(ag, scope, value->source_node, value);
5602     } else if (result_loc != nullptr) {
5603         return ir_expr_wrap(ag, scope, value, result_loc);
5604     } else {
5605         return value;
5606     }
5607 
5608 }
5609 
star_token_to_ptr_len(TokenId token_id)5610 static PtrLen star_token_to_ptr_len(TokenId token_id) {
5611     switch (token_id) {
5612         case TokenIdStar:
5613         case TokenIdStarStar:
5614             return PtrLenSingle;
5615         case TokenIdLBracket:
5616             return PtrLenUnknown;
5617         case TokenIdIdentifier:
5618             return PtrLenC;
5619         default:
5620             zig_unreachable();
5621     }
5622 }
5623 
token_number_literal_u32(Stage1AstGen * ag,AstNode * source_node,RootStruct * root_struct,uint32_t * result,TokenIndex token)5624 static Error token_number_literal_u32(Stage1AstGen *ag, AstNode *source_node,
5625     RootStruct *root_struct, uint32_t *result, TokenIndex token)
5626 {
5627     BigInt bigint;
5628     token_number_literal_bigint(root_struct, &bigint, token);
5629 
5630     if (!bigint_fits_in_bits(&bigint, 32, false)) {
5631         Buf *val_buf = buf_alloc();
5632         bigint_append_buf(val_buf, &bigint, 10);
5633         exec_add_error_node(ag->codegen, ag->exec, source_node,
5634                 buf_sprintf("value %s too large for u32", buf_ptr(val_buf)));
5635         bigint_deinit(&bigint);
5636         return ErrorSemanticAnalyzeFail;
5637     }
5638     *result = bigint_as_u32(&bigint);
5639     bigint_deinit(&bigint);
5640     return ErrorNone;
5641 
5642 }
5643 
astgen_pointer_type(Stage1AstGen * ag,Scope * scope,AstNode * node)5644 static Stage1ZirInst *astgen_pointer_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {
5645     Error err;
5646     assert(node->type == NodeTypePointerType);
5647 
5648     RootStruct *root_struct = node->owner->data.structure.root_struct;
5649     TokenId star_tok_id = root_struct->token_ids[node->data.pointer_type.star_token];
5650     PtrLen ptr_len = star_token_to_ptr_len(star_tok_id);
5651 
5652     bool is_const = node->data.pointer_type.is_const;
5653     bool is_volatile = node->data.pointer_type.is_volatile;
5654     bool is_allow_zero = node->data.pointer_type.allow_zero_token != 0;
5655     AstNode *sentinel_expr = node->data.pointer_type.sentinel;
5656     AstNode *expr_node = node->data.pointer_type.op_expr;
5657     AstNode *align_expr = node->data.pointer_type.align_expr;
5658 
5659     Stage1ZirInst *sentinel;
5660     if (sentinel_expr != nullptr) {
5661         sentinel = astgen_node(ag, sentinel_expr, scope);
5662         if (sentinel == ag->codegen->invalid_inst_src)
5663             return sentinel;
5664     } else {
5665         sentinel = nullptr;
5666     }
5667 
5668     Stage1ZirInst *align_value;
5669     if (align_expr != nullptr) {
5670         align_value = astgen_node(ag, align_expr, scope);
5671         if (align_value == ag->codegen->invalid_inst_src)
5672             return align_value;
5673     } else {
5674         align_value = nullptr;
5675     }
5676 
5677     Stage1ZirInst *child_type = astgen_node(ag, expr_node, scope);
5678     if (child_type == ag->codegen->invalid_inst_src)
5679         return child_type;
5680 
5681     uint32_t bit_offset_start = 0;
5682     if (node->data.pointer_type.bit_offset_start != 0) {
5683         if ((err = token_number_literal_u32(ag, node, root_struct, &bit_offset_start,
5684             node->data.pointer_type.bit_offset_start)))
5685         {
5686             return ag->codegen->invalid_inst_src;
5687         }
5688     }
5689 
5690     uint32_t host_int_bytes = 0;
5691     if (node->data.pointer_type.host_int_bytes != 0) {
5692         if ((err = token_number_literal_u32(ag, node, root_struct, &host_int_bytes,
5693             node->data.pointer_type.host_int_bytes)))
5694         {
5695             return ag->codegen->invalid_inst_src;
5696         }
5697     }
5698 
5699     if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) {
5700         exec_add_error_node(ag->codegen, ag->exec, node,
5701                 buf_sprintf("bit offset starts after end of host integer"));
5702         return ag->codegen->invalid_inst_src;
5703     }
5704 
5705     return ir_build_ptr_type(ag, scope, node, child_type, is_const, is_volatile,
5706             ptr_len, sentinel, align_value, bit_offset_start, host_int_bytes, is_allow_zero);
5707 }
5708 
astgen_catch_unreachable(Stage1AstGen * ag,Scope * scope,AstNode * source_node,AstNode * expr_node,LVal lval,ResultLoc * result_loc)5709 static Stage1ZirInst *astgen_catch_unreachable(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
5710         AstNode *expr_node, LVal lval, ResultLoc *result_loc)
5711 {
5712     Stage1ZirInst *err_union_ptr = astgen_node_extra(ag, expr_node, scope, LValPtr, nullptr);
5713     if (err_union_ptr == ag->codegen->invalid_inst_src)
5714         return ag->codegen->invalid_inst_src;
5715 
5716     Stage1ZirInst *payload_ptr = ir_build_unwrap_err_payload_src(ag, scope, source_node, err_union_ptr, true, false);
5717     if (payload_ptr == ag->codegen->invalid_inst_src)
5718         return ag->codegen->invalid_inst_src;
5719 
5720     if (lval == LValPtr)
5721         return payload_ptr;
5722 
5723     Stage1ZirInst *load_ptr = ir_build_load_ptr(ag, scope, source_node, payload_ptr);
5724     return ir_expr_wrap(ag, scope, load_ptr, result_loc);
5725 }
5726 
astgen_bool_not(Stage1AstGen * ag,Scope * scope,AstNode * node)5727 static Stage1ZirInst *astgen_bool_not(Stage1AstGen *ag, Scope *scope, AstNode *node) {
5728     assert(node->type == NodeTypePrefixOpExpr);
5729     AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
5730 
5731     Stage1ZirInst *value = astgen_node(ag, expr_node, scope);
5732     if (value == ag->codegen->invalid_inst_src)
5733         return ag->codegen->invalid_inst_src;
5734 
5735     return ir_build_bool_not(ag, scope, node, value);
5736 }
5737 
astgen_prefix_op_expr(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)5738 static Stage1ZirInst *astgen_prefix_op_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
5739         ResultLoc *result_loc)
5740 {
5741     assert(node->type == NodeTypePrefixOpExpr);
5742 
5743     PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op;
5744 
5745     switch (prefix_op) {
5746         case PrefixOpInvalid:
5747             zig_unreachable();
5748         case PrefixOpBoolNot:
5749             return ir_lval_wrap(ag, scope, astgen_bool_not(ag, scope, node), lval, result_loc);
5750         case PrefixOpBinNot:
5751             return ir_lval_wrap(ag, scope, astgen_prefix_op_id(ag, scope, node, IrUnOpBinNot), lval, result_loc);
5752         case PrefixOpNegation:
5753             return ir_lval_wrap(ag, scope, astgen_prefix_op_id(ag, scope, node, IrUnOpNegation), lval, result_loc);
5754         case PrefixOpNegationWrap:
5755             return ir_lval_wrap(ag, scope, astgen_prefix_op_id(ag, scope, node, IrUnOpNegationWrap), lval, result_loc);
5756         case PrefixOpOptional:
5757             return ir_lval_wrap(ag, scope, astgen_prefix_op_id(ag, scope, node, IrUnOpOptional), lval, result_loc);
5758         case PrefixOpAddrOf: {
5759             AstNode *expr_node = node->data.prefix_op_expr.primary_expr;
5760             return ir_lval_wrap(ag, scope, astgen_node_extra(ag, expr_node, scope, LValPtr, nullptr), lval, result_loc);
5761         }
5762     }
5763     zig_unreachable();
5764 }
5765 
astgen_union_init_expr(Stage1AstGen * ag,Scope * scope,AstNode * source_node,Stage1ZirInst * union_type,Stage1ZirInst * field_name,AstNode * expr_node,LVal lval,ResultLoc * parent_result_loc)5766 static Stage1ZirInst *astgen_union_init_expr(Stage1AstGen *ag, Scope *scope, AstNode *source_node,
5767     Stage1ZirInst *union_type, Stage1ZirInst *field_name, AstNode *expr_node,
5768     LVal lval, ResultLoc *parent_result_loc)
5769 {
5770     Stage1ZirInst *container_ptr = ir_build_resolve_result(ag, scope, source_node, parent_result_loc, union_type);
5771     Stage1ZirInst *field_ptr = ir_build_field_ptr_instruction(ag, scope, source_node, container_ptr,
5772             field_name, true);
5773 
5774     ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
5775     result_loc_inst->base.id = ResultLocIdInstruction;
5776     result_loc_inst->base.source_instruction = field_ptr;
5777     ir_ref_instruction(field_ptr, ag->current_basic_block);
5778     ir_build_reset_result(ag, scope, expr_node, &result_loc_inst->base);
5779 
5780     Stage1ZirInst *expr_value = astgen_node_extra(ag, expr_node, scope, LValNone,
5781             &result_loc_inst->base);
5782     if (expr_value == ag->codegen->invalid_inst_src)
5783         return expr_value;
5784 
5785     Stage1ZirInst *init_union = ir_build_union_init_named_field(ag, scope, source_node, union_type,
5786             field_name, field_ptr, container_ptr);
5787 
5788     return ir_lval_wrap(ag, scope, init_union, lval, parent_result_loc);
5789 }
5790 
astgen_container_init_expr(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * parent_result_loc)5791 static Stage1ZirInst *astgen_container_init_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
5792         ResultLoc *parent_result_loc)
5793 {
5794     assert(node->type == NodeTypeContainerInitExpr);
5795 
5796     AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
5797     ContainerInitKind kind = container_init_expr->kind;
5798 
5799     ResultLocCast *result_loc_cast = nullptr;
5800     ResultLoc *child_result_loc;
5801     AstNode *init_array_type_source_node;
5802     if (container_init_expr->type != nullptr) {
5803         Stage1ZirInst *container_type;
5804         if (container_init_expr->type->type == NodeTypeInferredArrayType) {
5805             if (kind == ContainerInitKindStruct) {
5806                 add_node_error(ag->codegen, container_init_expr->type,
5807                         buf_sprintf("initializing array with struct syntax"));
5808                 return ag->codegen->invalid_inst_src;
5809             }
5810             Stage1ZirInst *sentinel;
5811             if (container_init_expr->type->data.inferred_array_type.sentinel != nullptr) {
5812                 sentinel = astgen_node(ag, container_init_expr->type->data.inferred_array_type.sentinel, scope);
5813                 if (sentinel == ag->codegen->invalid_inst_src)
5814                     return sentinel;
5815             } else {
5816                 sentinel = nullptr;
5817             }
5818 
5819             Stage1ZirInst *elem_type = astgen_node(ag,
5820                     container_init_expr->type->data.inferred_array_type.child_type, scope);
5821             if (elem_type == ag->codegen->invalid_inst_src)
5822                 return elem_type;
5823             size_t item_count = container_init_expr->entries.length;
5824             Stage1ZirInst *item_count_inst = ir_build_const_usize(ag, scope, node, item_count);
5825             container_type = ir_build_array_type(ag, scope, node, item_count_inst, sentinel, elem_type);
5826         } else {
5827             container_type = astgen_node(ag, container_init_expr->type, scope);
5828             if (container_type == ag->codegen->invalid_inst_src)
5829                 return container_type;
5830         }
5831 
5832         result_loc_cast = ir_build_cast_result_loc(ag, container_type, parent_result_loc);
5833         child_result_loc = &result_loc_cast->base;
5834         init_array_type_source_node = container_type->source_node;
5835     } else {
5836         child_result_loc = parent_result_loc;
5837         if (parent_result_loc->source_instruction != nullptr) {
5838             init_array_type_source_node = parent_result_loc->source_instruction->source_node;
5839         } else {
5840             init_array_type_source_node = node;
5841         }
5842     }
5843 
5844     switch (kind) {
5845         case ContainerInitKindStruct: {
5846             Stage1ZirInst *container_ptr = ir_build_resolve_result(ag, scope, node, child_result_loc,
5847                     nullptr);
5848 
5849             size_t field_count = container_init_expr->entries.length;
5850             Stage1ZirInstContainerInitFieldsField *fields = heap::c_allocator.allocate<Stage1ZirInstContainerInitFieldsField>(field_count);
5851             for (size_t i = 0; i < field_count; i += 1) {
5852                 AstNode *entry_node = container_init_expr->entries.at(i);
5853                 assert(entry_node->type == NodeTypeStructValueField);
5854 
5855                 Buf *name = entry_node->data.struct_val_field.name;
5856                 AstNode *expr_node = entry_node->data.struct_val_field.expr;
5857 
5858                 Stage1ZirInst *field_ptr = ir_build_field_ptr(ag, scope, entry_node, container_ptr, name, true);
5859                 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
5860                 result_loc_inst->base.id = ResultLocIdInstruction;
5861                 result_loc_inst->base.source_instruction = field_ptr;
5862                 result_loc_inst->base.allow_write_through_const = true;
5863                 ir_ref_instruction(field_ptr, ag->current_basic_block);
5864                 ir_build_reset_result(ag, scope, expr_node, &result_loc_inst->base);
5865 
5866                 Stage1ZirInst *expr_value = astgen_node_extra(ag, expr_node, scope, LValNone,
5867                         &result_loc_inst->base);
5868                 if (expr_value == ag->codegen->invalid_inst_src)
5869                     return expr_value;
5870 
5871                 fields[i].name = name;
5872                 fields[i].source_node = entry_node;
5873                 fields[i].result_loc = field_ptr;
5874             }
5875             Stage1ZirInst *result = ir_build_container_init_fields(ag, scope, node, field_count,
5876                     fields, container_ptr);
5877 
5878             if (result_loc_cast != nullptr) {
5879                 result = ir_build_implicit_cast(ag, scope, node, result, result_loc_cast);
5880             }
5881             return ir_lval_wrap(ag, scope, result, lval, parent_result_loc);
5882         }
5883         case ContainerInitKindArray: {
5884             size_t item_count = container_init_expr->entries.length;
5885 
5886             Stage1ZirInst *container_ptr = ir_build_resolve_result(ag, scope, node, child_result_loc,
5887                     nullptr);
5888 
5889             Stage1ZirInst **result_locs = heap::c_allocator.allocate<Stage1ZirInst *>(item_count);
5890             for (size_t i = 0; i < item_count; i += 1) {
5891                 AstNode *expr_node = container_init_expr->entries.at(i);
5892 
5893                 Stage1ZirInst *elem_index = ir_build_const_usize(ag, scope, expr_node, i);
5894                 Stage1ZirInst *elem_ptr = ir_build_elem_ptr(ag, scope, expr_node, container_ptr,
5895                         elem_index, false, PtrLenSingle, init_array_type_source_node);
5896                 ResultLocInstruction *result_loc_inst = heap::c_allocator.create<ResultLocInstruction>();
5897                 result_loc_inst->base.id = ResultLocIdInstruction;
5898                 result_loc_inst->base.source_instruction = elem_ptr;
5899                 result_loc_inst->base.allow_write_through_const = true;
5900                 ir_ref_instruction(elem_ptr, ag->current_basic_block);
5901                 ir_build_reset_result(ag, scope, expr_node, &result_loc_inst->base);
5902 
5903                 Stage1ZirInst *expr_value = astgen_node_extra(ag, expr_node, scope, LValNone,
5904                         &result_loc_inst->base);
5905                 if (expr_value == ag->codegen->invalid_inst_src)
5906                     return expr_value;
5907 
5908                 result_locs[i] = elem_ptr;
5909             }
5910             Stage1ZirInst *result = ir_build_container_init_list(ag, scope, node, item_count,
5911                     result_locs, container_ptr, init_array_type_source_node);
5912             if (result_loc_cast != nullptr) {
5913                 result = ir_build_implicit_cast(ag, scope, node, result, result_loc_cast);
5914             }
5915             return ir_lval_wrap(ag, scope, result, lval, parent_result_loc);
5916         }
5917     }
5918     zig_unreachable();
5919 }
5920 
ir_build_var_result_loc(Stage1AstGen * ag,Stage1ZirInst * alloca,ZigVar * var)5921 static ResultLocVar *ir_build_var_result_loc(Stage1AstGen *ag, Stage1ZirInst *alloca, ZigVar *var) {
5922     ResultLocVar *result_loc_var = heap::c_allocator.create<ResultLocVar>();
5923     result_loc_var->base.id = ResultLocIdVar;
5924     result_loc_var->base.source_instruction = alloca;
5925     result_loc_var->base.allow_write_through_const = true;
5926     result_loc_var->var = var;
5927 
5928     ir_build_reset_result(ag, alloca->scope, alloca->source_node, &result_loc_var->base);
5929 
5930     return result_loc_var;
5931 }
5932 
ir_build_cast_result_loc(Stage1AstGen * ag,Stage1ZirInst * dest_type,ResultLoc * parent_result_loc)5933 static ResultLocCast *ir_build_cast_result_loc(Stage1AstGen *ag, Stage1ZirInst *dest_type,
5934         ResultLoc *parent_result_loc)
5935 {
5936     ResultLocCast *result_loc_cast = heap::c_allocator.create<ResultLocCast>();
5937     result_loc_cast->base.id = ResultLocIdCast;
5938     result_loc_cast->base.source_instruction = dest_type;
5939     result_loc_cast->base.allow_write_through_const = parent_result_loc->allow_write_through_const;
5940     ir_ref_instruction(dest_type, ag->current_basic_block);
5941     result_loc_cast->parent = parent_result_loc;
5942 
5943     ir_build_reset_result(ag, dest_type->scope, dest_type->source_node, &result_loc_cast->base);
5944 
5945     return result_loc_cast;
5946 }
5947 
build_decl_var_and_init(Stage1AstGen * ag,Scope * scope,AstNode * source_node,ZigVar * var,Stage1ZirInst * init,const char * name_hint,Stage1ZirInst * is_comptime)5948 static void build_decl_var_and_init(Stage1AstGen *ag, Scope *scope, AstNode *source_node, ZigVar *var,
5949         Stage1ZirInst *init, const char *name_hint, Stage1ZirInst *is_comptime)
5950 {
5951     Stage1ZirInst *alloca = ir_build_alloca_src(ag, scope, source_node, nullptr, name_hint, is_comptime);
5952     ResultLocVar *var_result_loc = ir_build_var_result_loc(ag, alloca, var);
5953     ir_build_end_expr(ag, scope, source_node, init, &var_result_loc->base);
5954     ir_build_var_decl_src(ag, scope, source_node, var, nullptr, alloca);
5955 }
5956 
astgen_var_decl(Stage1AstGen * ag,Scope * scope,AstNode * node)5957 static Stage1ZirInst *astgen_var_decl(Stage1AstGen *ag, Scope *scope, AstNode *node) {
5958     assert(node->type == NodeTypeVariableDeclaration);
5959 
5960     AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration;
5961 
5962     if (buf_eql_str(variable_declaration->symbol, "_")) {
5963         add_node_error(ag->codegen, node, buf_sprintf("`_` is not a declarable symbol"));
5964         return ag->codegen->invalid_inst_src;
5965     }
5966 
5967     // Used for the type expr and the align expr
5968     Scope *comptime_scope = create_comptime_scope(ag->codegen, node, scope);
5969 
5970     Stage1ZirInst *type_instruction;
5971     if (variable_declaration->type != nullptr) {
5972         type_instruction = astgen_node(ag, variable_declaration->type, comptime_scope);
5973         if (type_instruction == ag->codegen->invalid_inst_src)
5974             return type_instruction;
5975     } else {
5976         type_instruction = nullptr;
5977     }
5978 
5979     bool is_shadowable = false;
5980     bool is_const = variable_declaration->is_const;
5981     bool is_extern = variable_declaration->is_extern;
5982 
5983     bool is_comptime_scalar = ir_should_inline(ag->exec, scope) || variable_declaration->is_comptime;
5984     Stage1ZirInst *is_comptime = ir_build_const_bool(ag, scope, node, is_comptime_scalar);
5985     ZigVar *var = ir_create_var(ag, node, scope, variable_declaration->symbol,
5986         is_const, is_const, is_shadowable, is_comptime);
5987     // we detect Stage1ZirInstDeclVar in gen_block to make sure the next node
5988     // is inside var->child_scope
5989 
5990     if (!is_extern && !variable_declaration->expr) {
5991         var->var_type = ag->codegen->builtin_types.entry_invalid;
5992         add_node_error(ag->codegen, node, buf_sprintf("variables must be initialized"));
5993         return ag->codegen->invalid_inst_src;
5994     }
5995 
5996     Stage1ZirInst *align_value = nullptr;
5997     if (variable_declaration->align_expr != nullptr) {
5998         align_value = astgen_node(ag, variable_declaration->align_expr, comptime_scope);
5999         if (align_value == ag->codegen->invalid_inst_src)
6000             return align_value;
6001     }
6002 
6003     if (variable_declaration->section_expr != nullptr) {
6004         add_node_error(ag->codegen, variable_declaration->section_expr,
6005             buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol)));
6006     }
6007 
6008     // Parser should ensure that this never happens
6009     assert(variable_declaration->threadlocal_tok == 0);
6010 
6011     Stage1ZirInst *alloca = ir_build_alloca_src(ag, scope, node, align_value,
6012             buf_ptr(variable_declaration->symbol), is_comptime);
6013 
6014     // Create a result location for the initialization expression.
6015     ResultLocVar *result_loc_var = ir_build_var_result_loc(ag, alloca, var);
6016     ResultLoc *init_result_loc;
6017     ResultLocCast *result_loc_cast;
6018     if (type_instruction != nullptr) {
6019         result_loc_cast = ir_build_cast_result_loc(ag, type_instruction, &result_loc_var->base);
6020         init_result_loc = &result_loc_cast->base;
6021     } else {
6022         result_loc_cast = nullptr;
6023         init_result_loc = &result_loc_var->base;
6024     }
6025 
6026     Scope *init_scope = is_comptime_scalar ?
6027         create_comptime_scope(ag->codegen, variable_declaration->expr, scope) : scope;
6028 
6029     // Temporarily set the name of the Stage1Zir to the VariableDeclaration
6030     // so that the struct or enum from the init expression inherits the name.
6031     Buf *old_exec_name = ag->exec->name;
6032     ag->exec->name = variable_declaration->symbol;
6033     Stage1ZirInst *init_value = astgen_node_extra(ag, variable_declaration->expr, init_scope,
6034             LValNone, init_result_loc);
6035     ag->exec->name = old_exec_name;
6036 
6037     if (init_value == ag->codegen->invalid_inst_src)
6038         return ag->codegen->invalid_inst_src;
6039 
6040     if (result_loc_cast != nullptr) {
6041         Stage1ZirInst *implicit_cast = ir_build_implicit_cast(ag, scope, init_value->source_node,
6042                 init_value, result_loc_cast);
6043         ir_build_end_expr(ag, scope, node, implicit_cast, &result_loc_var->base);
6044     }
6045 
6046     return ir_build_var_decl_src(ag, scope, node, var, align_value, alloca);
6047 }
6048 
astgen_while_expr(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)6049 static Stage1ZirInst *astgen_while_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
6050         ResultLoc *result_loc)
6051 {
6052     assert(node->type == NodeTypeWhileExpr);
6053 
6054     AstNode *continue_expr_node = node->data.while_expr.continue_expr;
6055     AstNode *else_node = node->data.while_expr.else_node;
6056 
6057     Stage1ZirBasicBlock *cond_block = ir_create_basic_block(ag, scope, "WhileCond");
6058     Stage1ZirBasicBlock *body_block = ir_create_basic_block(ag, scope, "WhileBody");
6059     Stage1ZirBasicBlock *continue_block = continue_expr_node ?
6060         ir_create_basic_block(ag, scope, "WhileContinue") : cond_block;
6061     Stage1ZirBasicBlock *end_block = ir_create_basic_block(ag, scope, "WhileEnd");
6062     Stage1ZirBasicBlock *else_block = else_node ?
6063         ir_create_basic_block(ag, scope, "WhileElse") : end_block;
6064 
6065     Stage1ZirInst *is_comptime = ir_build_const_bool(ag, scope, node,
6066         ir_should_inline(ag->exec, scope) || node->data.while_expr.is_inline);
6067     ir_build_br(ag, scope, node, cond_block, is_comptime);
6068 
6069     Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
6070     Buf *var_symbol = node->data.while_expr.var_symbol;
6071     Buf *err_symbol = node->data.while_expr.err_symbol;
6072     if (err_symbol != nullptr) {
6073         ir_set_cursor_at_end_and_append_block(ag, cond_block);
6074 
6075         Scope *payload_scope;
6076         AstNode *symbol_node = node; // TODO make more accurate
6077         ZigVar *payload_var;
6078         if (var_symbol) {
6079             // TODO make it an error to write to payload variable
6080             payload_var = ir_create_var(ag, symbol_node, subexpr_scope, var_symbol,
6081                     true, false, false, is_comptime);
6082             payload_scope = payload_var->child_scope;
6083         } else {
6084             payload_scope = subexpr_scope;
6085         }
6086         ScopeExpr *spill_scope = create_expr_scope(ag->codegen, node, payload_scope);
6087         Stage1ZirInst *err_val_ptr = astgen_node_extra(ag, node->data.while_expr.condition, subexpr_scope,
6088                 LValPtr, nullptr);
6089         if (err_val_ptr == ag->codegen->invalid_inst_src)
6090             return err_val_ptr;
6091         Stage1ZirInst *is_err = ir_build_test_err_src(ag, scope, node->data.while_expr.condition, err_val_ptr,
6092                 true, false);
6093         Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6094         Stage1ZirInst *void_else_result = else_node ? nullptr : ir_build_const_void(ag, scope, node);
6095         Stage1ZirInst *cond_br_inst;
6096         if (!instr_is_unreachable(is_err)) {
6097             cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_err,
6098                         else_block, body_block, is_comptime);
6099         } else {
6100             // for the purposes of the source instruction to ir_build_result_peers
6101             cond_br_inst = ag->current_basic_block->instruction_list.last();
6102         }
6103 
6104         ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc,
6105                 is_comptime);
6106 
6107         ir_set_cursor_at_end_and_append_block(ag, body_block);
6108         if (var_symbol) {
6109             Stage1ZirInst *payload_ptr = ir_build_unwrap_err_payload_src(ag, &spill_scope->base, symbol_node,
6110                     err_val_ptr, false, false);
6111             Stage1ZirInst *var_value = node->data.while_expr.var_is_ptr ?
6112                 payload_ptr : ir_build_load_ptr(ag, &spill_scope->base, symbol_node, payload_ptr);
6113             build_decl_var_and_init(ag, payload_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime);
6114         }
6115 
6116         ZigList<Stage1ZirInst *> incoming_values = {0};
6117         ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
6118 
6119         if (is_duplicate_label(ag->codegen, payload_scope, node, node->data.while_expr.name))
6120             return ag->codegen->invalid_inst_src;
6121 
6122         ScopeLoop *loop_scope = create_loop_scope(ag->codegen, node, payload_scope);
6123         loop_scope->break_block = end_block;
6124         loop_scope->continue_block = continue_block;
6125         loop_scope->is_comptime = is_comptime;
6126         loop_scope->incoming_blocks = &incoming_blocks;
6127         loop_scope->incoming_values = &incoming_values;
6128         loop_scope->lval = lval;
6129         loop_scope->peer_parent = peer_parent;
6130         loop_scope->spill_scope = spill_scope;
6131 
6132         // Note the body block of the loop is not the place that lval and result_loc are used -
6133         // it's actually in break statements, handled similarly to return statements.
6134         // That is why we set those values in loop_scope above and not in this astgen_node call.
6135         Stage1ZirInst *body_result = astgen_node(ag, node->data.while_expr.body, &loop_scope->base);
6136         if (body_result == ag->codegen->invalid_inst_src)
6137             return body_result;
6138 
6139         if (loop_scope->name != nullptr && loop_scope->name_used == false) {
6140             add_node_error(ag->codegen, node, buf_sprintf("unused while label"));
6141         }
6142 
6143         if (!instr_is_unreachable(body_result)) {
6144             ir_build_check_statement_is_void(ag, payload_scope, node->data.while_expr.body, body_result);
6145             ir_build_br(ag, payload_scope, node, continue_block, is_comptime);
6146         }
6147 
6148         if (continue_expr_node) {
6149             ir_set_cursor_at_end_and_append_block(ag, continue_block);
6150             Stage1ZirInst *expr_result = astgen_node(ag, continue_expr_node, payload_scope);
6151             if (expr_result == ag->codegen->invalid_inst_src)
6152                 return expr_result;
6153             if (!instr_is_unreachable(expr_result)) {
6154                 ir_build_check_statement_is_void(ag, payload_scope, continue_expr_node, expr_result);
6155                 ir_build_br(ag, payload_scope, node, cond_block, is_comptime);
6156             }
6157         }
6158 
6159         ir_set_cursor_at_end_and_append_block(ag, else_block);
6160         assert(else_node != nullptr);
6161 
6162         // TODO make it an error to write to error variable
6163         AstNode *err_symbol_node = else_node; // TODO make more accurate
6164         ZigVar *err_var = ir_create_var(ag, err_symbol_node, scope, err_symbol,
6165                 true, false, false, is_comptime);
6166         Scope *err_scope = err_var->child_scope;
6167         Stage1ZirInst *err_ptr = ir_build_unwrap_err_code_src(ag, err_scope, err_symbol_node, err_val_ptr);
6168         Stage1ZirInst *err_value = ir_build_load_ptr(ag, err_scope, err_symbol_node, err_ptr);
6169         build_decl_var_and_init(ag, err_scope, err_symbol_node, err_var, err_value, buf_ptr(err_symbol), is_comptime);
6170 
6171         if (peer_parent->peers.length != 0) {
6172             peer_parent->peers.last()->next_bb = else_block;
6173         }
6174         ResultLocPeer *peer_result = create_peer_result(peer_parent);
6175         peer_parent->peers.append(peer_result);
6176         Stage1ZirInst *else_result = astgen_node_extra(ag, else_node, err_scope, lval, &peer_result->base);
6177         if (else_result == ag->codegen->invalid_inst_src)
6178             return else_result;
6179         if (!instr_is_unreachable(else_result))
6180             ir_build_br(ag, scope, node, end_block, is_comptime);
6181         Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6182         ir_set_cursor_at_end_and_append_block(ag, end_block);
6183         if (else_result) {
6184             incoming_blocks.append(after_else_block);
6185             incoming_values.append(else_result);
6186         } else {
6187             incoming_blocks.append(after_cond_block);
6188             incoming_values.append(void_else_result);
6189         }
6190         if (peer_parent->peers.length != 0) {
6191             peer_parent->peers.last()->next_bb = end_block;
6192         }
6193 
6194         Stage1ZirInst *phi = ir_build_phi(ag, scope, node, incoming_blocks.length,
6195                 incoming_blocks.items, incoming_values.items, peer_parent);
6196         return ir_expr_wrap(ag, scope, phi, result_loc);
6197     } else if (var_symbol != nullptr) {
6198         ir_set_cursor_at_end_and_append_block(ag, cond_block);
6199         Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
6200         // TODO make it an error to write to payload variable
6201         AstNode *symbol_node = node; // TODO make more accurate
6202 
6203         ZigVar *payload_var = ir_create_var(ag, symbol_node, subexpr_scope, var_symbol,
6204                 true, false, false, is_comptime);
6205         Scope *child_scope = payload_var->child_scope;
6206         ScopeExpr *spill_scope = create_expr_scope(ag->codegen, node, child_scope);
6207         Stage1ZirInst *maybe_val_ptr = astgen_node_extra(ag, node->data.while_expr.condition, subexpr_scope,
6208                 LValPtr, nullptr);
6209         if (maybe_val_ptr == ag->codegen->invalid_inst_src)
6210             return maybe_val_ptr;
6211         Stage1ZirInst *maybe_val = ir_build_load_ptr(ag, scope, node->data.while_expr.condition, maybe_val_ptr);
6212         Stage1ZirInst *is_non_null = ir_build_test_non_null_src(ag, scope, node->data.while_expr.condition, maybe_val);
6213         Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6214         Stage1ZirInst *void_else_result = else_node ? nullptr : ir_build_const_void(ag, scope, node);
6215         Stage1ZirInst *cond_br_inst;
6216         if (!instr_is_unreachable(is_non_null)) {
6217             cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, is_non_null,
6218                         body_block, else_block, is_comptime);
6219         } else {
6220             // for the purposes of the source instruction to ir_build_result_peers
6221             cond_br_inst = ag->current_basic_block->instruction_list.last();
6222         }
6223 
6224         ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc,
6225                 is_comptime);
6226 
6227         ir_set_cursor_at_end_and_append_block(ag, body_block);
6228         Stage1ZirInst *payload_ptr = ir_build_optional_unwrap_ptr(ag, &spill_scope->base, symbol_node, maybe_val_ptr, false);
6229         Stage1ZirInst *var_value = node->data.while_expr.var_is_ptr ?
6230             payload_ptr : ir_build_load_ptr(ag, &spill_scope->base, symbol_node, payload_ptr);
6231         build_decl_var_and_init(ag, child_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime);
6232 
6233         ZigList<Stage1ZirInst *> incoming_values = {0};
6234         ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
6235 
6236         if (is_duplicate_label(ag->codegen, child_scope, node, node->data.while_expr.name))
6237             return ag->codegen->invalid_inst_src;
6238 
6239         ScopeLoop *loop_scope = create_loop_scope(ag->codegen, node, child_scope);
6240         loop_scope->break_block = end_block;
6241         loop_scope->continue_block = continue_block;
6242         loop_scope->is_comptime = is_comptime;
6243         loop_scope->incoming_blocks = &incoming_blocks;
6244         loop_scope->incoming_values = &incoming_values;
6245         loop_scope->lval = lval;
6246         loop_scope->peer_parent = peer_parent;
6247         loop_scope->spill_scope = spill_scope;
6248 
6249         // Note the body block of the loop is not the place that lval and result_loc are used -
6250         // it's actually in break statements, handled similarly to return statements.
6251         // That is why we set those values in loop_scope above and not in this astgen_node call.
6252         Stage1ZirInst *body_result = astgen_node(ag, node->data.while_expr.body, &loop_scope->base);
6253         if (body_result == ag->codegen->invalid_inst_src)
6254             return body_result;
6255 
6256         if (loop_scope->name != nullptr && loop_scope->name_used == false) {
6257             add_node_error(ag->codegen, node, buf_sprintf("unused while label"));
6258         }
6259 
6260         if (!instr_is_unreachable(body_result)) {
6261             ir_build_check_statement_is_void(ag, child_scope, node->data.while_expr.body, body_result);
6262             ir_build_br(ag, child_scope, node, continue_block, is_comptime);
6263         }
6264 
6265         if (continue_expr_node) {
6266             ir_set_cursor_at_end_and_append_block(ag, continue_block);
6267             Stage1ZirInst *expr_result = astgen_node(ag, continue_expr_node, child_scope);
6268             if (expr_result == ag->codegen->invalid_inst_src)
6269                 return expr_result;
6270             if (!instr_is_unreachable(expr_result)) {
6271                 ir_build_check_statement_is_void(ag, child_scope, continue_expr_node, expr_result);
6272                 ir_build_br(ag, child_scope, node, cond_block, is_comptime);
6273             }
6274         }
6275 
6276         Stage1ZirInst *else_result = nullptr;
6277         if (else_node) {
6278             ir_set_cursor_at_end_and_append_block(ag, else_block);
6279 
6280             if (peer_parent->peers.length != 0) {
6281                 peer_parent->peers.last()->next_bb = else_block;
6282             }
6283             ResultLocPeer *peer_result = create_peer_result(peer_parent);
6284             peer_parent->peers.append(peer_result);
6285             else_result = astgen_node_extra(ag, else_node, scope, lval, &peer_result->base);
6286             if (else_result == ag->codegen->invalid_inst_src)
6287                 return else_result;
6288             if (!instr_is_unreachable(else_result))
6289                 ir_build_br(ag, scope, node, end_block, is_comptime);
6290         }
6291         Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6292         ir_set_cursor_at_end_and_append_block(ag, end_block);
6293         if (else_result) {
6294             incoming_blocks.append(after_else_block);
6295             incoming_values.append(else_result);
6296         } else {
6297             incoming_blocks.append(after_cond_block);
6298             incoming_values.append(void_else_result);
6299         }
6300         if (peer_parent->peers.length != 0) {
6301             peer_parent->peers.last()->next_bb = end_block;
6302         }
6303 
6304         Stage1ZirInst *phi = ir_build_phi(ag, scope, node, incoming_blocks.length,
6305                 incoming_blocks.items, incoming_values.items, peer_parent);
6306         return ir_expr_wrap(ag, scope, phi, result_loc);
6307     } else {
6308         ir_set_cursor_at_end_and_append_block(ag, cond_block);
6309         Stage1ZirInst *cond_val = astgen_node(ag, node->data.while_expr.condition, scope);
6310         if (cond_val == ag->codegen->invalid_inst_src)
6311             return cond_val;
6312         Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6313         Stage1ZirInst *void_else_result = else_node ? nullptr : ir_build_const_void(ag, scope, node);
6314         Stage1ZirInst *cond_br_inst;
6315         if (!instr_is_unreachable(cond_val)) {
6316             cond_br_inst = ir_build_cond_br(ag, scope, node->data.while_expr.condition, cond_val,
6317                         body_block, else_block, is_comptime);
6318         } else {
6319             // for the purposes of the source instruction to ir_build_result_peers
6320             cond_br_inst = ag->current_basic_block->instruction_list.last();
6321         }
6322 
6323         ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc,
6324                 is_comptime);
6325         ir_set_cursor_at_end_and_append_block(ag, body_block);
6326 
6327         ZigList<Stage1ZirInst *> incoming_values = {0};
6328         ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
6329 
6330         Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
6331 
6332         if (is_duplicate_label(ag->codegen, subexpr_scope, node, node->data.while_expr.name))
6333             return ag->codegen->invalid_inst_src;
6334 
6335         ScopeLoop *loop_scope = create_loop_scope(ag->codegen, node, subexpr_scope);
6336         loop_scope->break_block = end_block;
6337         loop_scope->continue_block = continue_block;
6338         loop_scope->is_comptime = is_comptime;
6339         loop_scope->incoming_blocks = &incoming_blocks;
6340         loop_scope->incoming_values = &incoming_values;
6341         loop_scope->lval = lval;
6342         loop_scope->peer_parent = peer_parent;
6343 
6344         // Note the body block of the loop is not the place that lval and result_loc are used -
6345         // it's actually in break statements, handled similarly to return statements.
6346         // That is why we set those values in loop_scope above and not in this astgen_node call.
6347         Stage1ZirInst *body_result = astgen_node(ag, node->data.while_expr.body, &loop_scope->base);
6348         if (body_result == ag->codegen->invalid_inst_src)
6349             return body_result;
6350 
6351         if (loop_scope->name != nullptr && loop_scope->name_used == false) {
6352             add_node_error(ag->codegen, node, buf_sprintf("unused while label"));
6353         }
6354 
6355         if (!instr_is_unreachable(body_result)) {
6356             ir_build_check_statement_is_void(ag, scope, node->data.while_expr.body, body_result);
6357             ir_build_br(ag, scope, node, continue_block, is_comptime);
6358         }
6359 
6360         if (continue_expr_node) {
6361             ir_set_cursor_at_end_and_append_block(ag, continue_block);
6362             Stage1ZirInst *expr_result = astgen_node(ag, continue_expr_node, subexpr_scope);
6363             if (expr_result == ag->codegen->invalid_inst_src)
6364                 return expr_result;
6365             if (!instr_is_unreachable(expr_result)) {
6366                 ir_build_check_statement_is_void(ag, scope, continue_expr_node, expr_result);
6367                 ir_build_br(ag, scope, node, cond_block, is_comptime);
6368             }
6369         }
6370 
6371         Stage1ZirInst *else_result = nullptr;
6372         if (else_node) {
6373             ir_set_cursor_at_end_and_append_block(ag, else_block);
6374 
6375             if (peer_parent->peers.length != 0) {
6376                 peer_parent->peers.last()->next_bb = else_block;
6377             }
6378             ResultLocPeer *peer_result = create_peer_result(peer_parent);
6379             peer_parent->peers.append(peer_result);
6380 
6381             else_result = astgen_node_extra(ag, else_node, subexpr_scope, lval, &peer_result->base);
6382             if (else_result == ag->codegen->invalid_inst_src)
6383                 return else_result;
6384             if (!instr_is_unreachable(else_result))
6385                 ir_build_br(ag, scope, node, end_block, is_comptime);
6386         }
6387         Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6388         ir_set_cursor_at_end_and_append_block(ag, end_block);
6389         if (else_result) {
6390             incoming_blocks.append(after_else_block);
6391             incoming_values.append(else_result);
6392         } else {
6393             incoming_blocks.append(after_cond_block);
6394             incoming_values.append(void_else_result);
6395         }
6396         if (peer_parent->peers.length != 0) {
6397             peer_parent->peers.last()->next_bb = end_block;
6398         }
6399 
6400         Stage1ZirInst *phi = ir_build_phi(ag, scope, node, incoming_blocks.length,
6401                 incoming_blocks.items, incoming_values.items, peer_parent);
6402         return ir_expr_wrap(ag, scope, phi, result_loc);
6403     }
6404 }
6405 
astgen_for_expr(Stage1AstGen * ag,Scope * parent_scope,AstNode * node,LVal lval,ResultLoc * result_loc)6406 static Stage1ZirInst *astgen_for_expr(Stage1AstGen *ag, Scope *parent_scope, AstNode *node, LVal lval,
6407         ResultLoc *result_loc)
6408 {
6409     assert(node->type == NodeTypeForExpr);
6410 
6411     AstNode *array_node = node->data.for_expr.array_expr;
6412     AstNode *elem_node = node->data.for_expr.elem_node;
6413     AstNode *index_node = node->data.for_expr.index_node;
6414     AstNode *body_node = node->data.for_expr.body;
6415     AstNode *else_node = node->data.for_expr.else_node;
6416 
6417     if (!elem_node) {
6418         add_node_error(ag->codegen, node, buf_sprintf("for loop expression missing element parameter"));
6419         return ag->codegen->invalid_inst_src;
6420     }
6421     assert(elem_node->type == NodeTypeIdentifier);
6422 
6423     ScopeExpr *spill_scope = create_expr_scope(ag->codegen, node, parent_scope);
6424 
6425     Stage1ZirInst *array_val_ptr = astgen_node_extra(ag, array_node, &spill_scope->base, LValPtr, nullptr);
6426     if (array_val_ptr == ag->codegen->invalid_inst_src)
6427         return array_val_ptr;
6428 
6429     Stage1ZirInst *is_comptime = ir_build_const_bool(ag, parent_scope, node,
6430         ir_should_inline(ag->exec, parent_scope) || node->data.for_expr.is_inline);
6431 
6432     AstNode *index_var_source_node;
6433     ZigVar *index_var;
6434     const char *index_var_name;
6435     if (index_node) {
6436         index_var_source_node = index_node;
6437         Buf *index_var_name_buf = node_identifier_buf(index_node);
6438         index_var = ir_create_var(ag, index_node, parent_scope, index_var_name_buf, true, false, false, is_comptime);
6439         index_var_name = buf_ptr(index_var_name_buf);
6440     } else {
6441         index_var_source_node = node;
6442         index_var = ir_create_var(ag, node, parent_scope, nullptr, true, false, true, is_comptime);
6443         index_var_name = "i";
6444     }
6445 
6446     Stage1ZirInst *zero = ir_build_const_usize(ag, parent_scope, node, 0);
6447     build_decl_var_and_init(ag, parent_scope, index_var_source_node, index_var, zero, index_var_name, is_comptime);
6448     parent_scope = index_var->child_scope;
6449 
6450     Stage1ZirInst *one = ir_build_const_usize(ag, parent_scope, node, 1);
6451     Stage1ZirInst *index_ptr = ir_build_var_ptr(ag, parent_scope, node, index_var);
6452 
6453 
6454     Stage1ZirBasicBlock *cond_block = ir_create_basic_block(ag, parent_scope, "ForCond");
6455     Stage1ZirBasicBlock *body_block = ir_create_basic_block(ag, parent_scope, "ForBody");
6456     Stage1ZirBasicBlock *end_block = ir_create_basic_block(ag, parent_scope, "ForEnd");
6457     Stage1ZirBasicBlock *else_block = else_node ? ir_create_basic_block(ag, parent_scope, "ForElse") : end_block;
6458     Stage1ZirBasicBlock *continue_block = ir_create_basic_block(ag, parent_scope, "ForContinue");
6459 
6460     Buf *len_field_name = buf_create_from_str("len");
6461     Stage1ZirInst *len_ref = ir_build_field_ptr(ag, parent_scope, node, array_val_ptr, len_field_name, false);
6462     Stage1ZirInst *len_val = ir_build_load_ptr(ag, &spill_scope->base, node, len_ref);
6463     ir_build_br(ag, parent_scope, node, cond_block, is_comptime);
6464 
6465     ir_set_cursor_at_end_and_append_block(ag, cond_block);
6466     Stage1ZirInst *index_val = ir_build_load_ptr(ag, &spill_scope->base, node, index_ptr);
6467     Stage1ZirInst *cond = ir_build_bin_op(ag, parent_scope, node, IrBinOpCmpLessThan, index_val, len_val, false);
6468     Stage1ZirBasicBlock *after_cond_block = ag->current_basic_block;
6469     Stage1ZirInst *void_else_value = else_node ? nullptr : ir_build_const_void(ag, parent_scope, node);
6470     Stage1ZirInst *cond_br_inst = ir_build_cond_br(ag, parent_scope, node, cond,
6471                 body_block, else_block, is_comptime);
6472 
6473     ResultLocPeerParent *peer_parent = ir_build_result_peers(ag, cond_br_inst, end_block, result_loc, is_comptime);
6474 
6475     ir_set_cursor_at_end_and_append_block(ag, body_block);
6476     Stage1ZirInst *elem_ptr = ir_build_elem_ptr(ag, &spill_scope->base, node, array_val_ptr, index_val,
6477             false, PtrLenSingle, nullptr);
6478     // TODO make it an error to write to element variable or i variable.
6479     Buf *elem_var_name = node_identifier_buf(elem_node);
6480     ZigVar *elem_var = ir_create_var(ag, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime);
6481     Scope *child_scope = elem_var->child_scope;
6482 
6483     Stage1ZirInst *elem_value = node->data.for_expr.elem_is_ptr ?
6484         elem_ptr : ir_build_load_ptr(ag, &spill_scope->base, elem_node, elem_ptr);
6485     build_decl_var_and_init(ag, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime);
6486 
6487     if (is_duplicate_label(ag->codegen, child_scope, node, node->data.for_expr.name))
6488         return ag->codegen->invalid_inst_src;
6489 
6490     ZigList<Stage1ZirInst *> incoming_values = {0};
6491     ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
6492     ScopeLoop *loop_scope = create_loop_scope(ag->codegen, node, child_scope);
6493     loop_scope->break_block = end_block;
6494     loop_scope->continue_block = continue_block;
6495     loop_scope->is_comptime = is_comptime;
6496     loop_scope->incoming_blocks = &incoming_blocks;
6497     loop_scope->incoming_values = &incoming_values;
6498     loop_scope->lval = LValNone;
6499     loop_scope->peer_parent = peer_parent;
6500     loop_scope->spill_scope = spill_scope;
6501 
6502     // Note the body block of the loop is not the place that lval and result_loc are used -
6503     // it's actually in break statements, handled similarly to return statements.
6504     // That is why we set those values in loop_scope above and not in this astgen_node call.
6505     Stage1ZirInst *body_result = astgen_node(ag, body_node, &loop_scope->base);
6506     if (body_result == ag->codegen->invalid_inst_src)
6507         return ag->codegen->invalid_inst_src;
6508 
6509     if (loop_scope->name != nullptr && loop_scope->name_used == false) {
6510         add_node_error(ag->codegen, node, buf_sprintf("unused for label"));
6511     }
6512 
6513     if (!instr_is_unreachable(body_result)) {
6514         ir_build_check_statement_is_void(ag, child_scope, node->data.for_expr.body, body_result);
6515         ir_build_br(ag, child_scope, node, continue_block, is_comptime);
6516     }
6517 
6518     ir_set_cursor_at_end_and_append_block(ag, continue_block);
6519     Stage1ZirInst *new_index_val = ir_build_bin_op(ag, child_scope, node, IrBinOpAdd, index_val, one, false);
6520     ir_build_store_ptr(ag, child_scope, node, index_ptr, new_index_val)->allow_write_through_const = true;
6521     ir_build_br(ag, child_scope, node, cond_block, is_comptime);
6522 
6523     Stage1ZirInst *else_result = nullptr;
6524     if (else_node) {
6525         ir_set_cursor_at_end_and_append_block(ag, else_block);
6526 
6527         if (peer_parent->peers.length != 0) {
6528             peer_parent->peers.last()->next_bb = else_block;
6529         }
6530         ResultLocPeer *peer_result = create_peer_result(peer_parent);
6531         peer_parent->peers.append(peer_result);
6532         else_result = astgen_node_extra(ag, else_node, parent_scope, LValNone, &peer_result->base);
6533         if (else_result == ag->codegen->invalid_inst_src)
6534             return else_result;
6535         if (!instr_is_unreachable(else_result))
6536             ir_build_br(ag, parent_scope, node, end_block, is_comptime);
6537     }
6538     Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6539     ir_set_cursor_at_end_and_append_block(ag, end_block);
6540 
6541     if (else_result) {
6542         incoming_blocks.append(after_else_block);
6543         incoming_values.append(else_result);
6544     } else {
6545         incoming_blocks.append(after_cond_block);
6546         incoming_values.append(void_else_value);
6547     }
6548     if (peer_parent->peers.length != 0) {
6549         peer_parent->peers.last()->next_bb = end_block;
6550     }
6551 
6552     Stage1ZirInst *phi = ir_build_phi(ag, parent_scope, node, incoming_blocks.length,
6553             incoming_blocks.items, incoming_values.items, peer_parent);
6554     return ir_lval_wrap(ag, parent_scope, phi, lval, result_loc);
6555 }
6556 
astgen_bool_literal(Stage1AstGen * ag,Scope * scope,AstNode * node)6557 static Stage1ZirInst *astgen_bool_literal(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6558     assert(node->type == NodeTypeBoolLiteral);
6559     return ir_build_const_bool(ag, scope, node, node->data.bool_literal.value);
6560 }
6561 
astgen_enum_literal(Stage1AstGen * ag,Scope * scope,AstNode * node)6562 static Stage1ZirInst *astgen_enum_literal(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6563     assert(node->type == NodeTypeEnumLiteral);
6564     // Currently, stage1 runs astgen for every comptime function call,
6565     // resulting the allocation here wasting memory. As a workaround until
6566     // the code is adjusted to make astgen run only once per source node,
6567     // we memoize the result into the AST here.
6568     if (node->data.enum_literal.name == nullptr) {
6569         RootStruct *root_struct = node->owner->data.structure.root_struct;
6570         node->data.enum_literal.name = token_identifier_buf(root_struct, node->main_token + 1);
6571     }
6572     return ir_build_const_enum_literal(ag, scope, node, node->data.enum_literal.name);
6573 }
6574 
astgen_string_literal(Stage1AstGen * ag,Scope * scope,AstNode * node)6575 static Stage1ZirInst *astgen_string_literal(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6576     Error err;
6577     assert(node->type == NodeTypeStringLiteral);
6578 
6579     RootStruct *root_struct = node->owner->data.structure.root_struct;
6580     const char *source = buf_ptr(root_struct->source_code);
6581 
6582     TokenId *token_ids = root_struct->token_ids;
6583 
6584     Buf *str = buf_alloc();
6585     if (token_ids[node->main_token] == TokenIdStringLiteral) {
6586         size_t byte_offset = root_struct->token_locs[node->main_token].offset;
6587         size_t bad_index;
6588         if ((err = source_string_literal_buf(source + byte_offset, str, &bad_index))) {
6589             add_token_error_offset(ag->codegen, node->owner, node->main_token,
6590                     buf_create_from_str("invalid string literal character"), bad_index);
6591         }
6592         src_assert(source[byte_offset] == '"', node);
6593         byte_offset += 1;
6594     } else if (token_ids[node->main_token] == TokenIdMultilineStringLiteralLine) {
6595         TokenIndex tok_index = node->main_token;
6596         bool first = true;
6597         for (;token_ids[tok_index] == TokenIdMultilineStringLiteralLine; tok_index += 1) {
6598             size_t byte_offset = root_struct->token_locs[tok_index].offset;
6599             size_t end = byte_offset;
6600             while (source[end] != 0 && source[end] != '\n') {
6601                 end += 1;
6602             }
6603             if (!first) {
6604                 buf_append_char(str, '\n');
6605             } else {
6606                 first = false;
6607             }
6608             buf_append_mem(str, source + byte_offset + 2, end - byte_offset - 2);
6609         }
6610     } else {
6611         zig_unreachable();
6612     }
6613 
6614     return ir_build_const_str_lit(ag, scope, node, str);
6615 }
6616 
astgen_array_type(Stage1AstGen * ag,Scope * scope,AstNode * node)6617 static Stage1ZirInst *astgen_array_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6618     assert(node->type == NodeTypeArrayType);
6619 
6620     AstNode *size_node = node->data.array_type.size;
6621     AstNode *child_type_node = node->data.array_type.child_type;
6622     bool is_const = node->data.array_type.is_const;
6623     bool is_volatile = node->data.array_type.is_volatile;
6624     bool is_allow_zero = node->data.array_type.allow_zero_token != 0;
6625     AstNode *sentinel_expr = node->data.array_type.sentinel;
6626     AstNode *align_expr = node->data.array_type.align_expr;
6627 
6628     Scope *comptime_scope = create_comptime_scope(ag->codegen, node, scope);
6629 
6630     Stage1ZirInst *sentinel;
6631     if (sentinel_expr != nullptr) {
6632         sentinel = astgen_node(ag, sentinel_expr, comptime_scope);
6633         if (sentinel == ag->codegen->invalid_inst_src)
6634             return sentinel;
6635     } else {
6636         sentinel = nullptr;
6637     }
6638 
6639     if (size_node) {
6640         if (is_const) {
6641             add_node_error(ag->codegen, node, buf_create_from_str("const qualifier invalid on array type"));
6642             return ag->codegen->invalid_inst_src;
6643         }
6644         if (is_volatile) {
6645             add_node_error(ag->codegen, node, buf_create_from_str("volatile qualifier invalid on array type"));
6646             return ag->codegen->invalid_inst_src;
6647         }
6648         if (is_allow_zero) {
6649             add_node_error(ag->codegen, node, buf_create_from_str("allowzero qualifier invalid on array type"));
6650             return ag->codegen->invalid_inst_src;
6651         }
6652         if (align_expr != nullptr) {
6653             add_node_error(ag->codegen, node, buf_create_from_str("align qualifier invalid on array type"));
6654             return ag->codegen->invalid_inst_src;
6655         }
6656 
6657         Stage1ZirInst *size_value = astgen_node(ag, size_node, comptime_scope);
6658         if (size_value == ag->codegen->invalid_inst_src)
6659             return size_value;
6660 
6661         Stage1ZirInst *child_type = astgen_node(ag, child_type_node, comptime_scope);
6662         if (child_type == ag->codegen->invalid_inst_src)
6663             return child_type;
6664 
6665         return ir_build_array_type(ag, scope, node, size_value, sentinel, child_type);
6666     } else {
6667         Stage1ZirInst *align_value;
6668         if (align_expr != nullptr) {
6669             align_value = astgen_node(ag, align_expr, comptime_scope);
6670             if (align_value == ag->codegen->invalid_inst_src)
6671                 return align_value;
6672         } else {
6673             align_value = nullptr;
6674         }
6675 
6676         Stage1ZirInst *child_type = astgen_node(ag, child_type_node, comptime_scope);
6677         if (child_type == ag->codegen->invalid_inst_src)
6678             return child_type;
6679 
6680         return ir_build_slice_type(ag, scope, node, child_type, is_const, is_volatile, sentinel,
6681                 align_value, is_allow_zero);
6682     }
6683 }
6684 
astgen_anyframe_type(Stage1AstGen * ag,Scope * scope,AstNode * node)6685 static Stage1ZirInst *astgen_anyframe_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6686     assert(node->type == NodeTypeAnyFrameType);
6687 
6688     AstNode *payload_type_node = node->data.anyframe_type.payload_type;
6689     Stage1ZirInst *payload_type_value = nullptr;
6690 
6691     if (payload_type_node != nullptr) {
6692         payload_type_value = astgen_node(ag, payload_type_node, scope);
6693         if (payload_type_value == ag->codegen->invalid_inst_src)
6694             return payload_type_value;
6695 
6696     }
6697 
6698     return ir_build_anyframe_type(ag, scope, node, payload_type_value);
6699 }
6700 
astgen_undefined_literal(Stage1AstGen * ag,Scope * scope,AstNode * node)6701 static Stage1ZirInst *astgen_undefined_literal(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6702     assert(node->type == NodeTypeUndefinedLiteral);
6703     return ir_build_const_undefined(ag, scope, node);
6704 }
6705 
astgen_asm_expr(Stage1AstGen * ag,Scope * scope,AstNode * node)6706 static Stage1ZirInst *astgen_asm_expr(Stage1AstGen *ag, Scope *scope, AstNode *node) {
6707     assert(node->type == NodeTypeAsmExpr);
6708     AstNodeAsmExpr *asm_expr = &node->data.asm_expr;
6709 
6710     Stage1ZirInst *asm_template = astgen_node(ag, asm_expr->asm_template, scope);
6711     if (asm_template == ag->codegen->invalid_inst_src)
6712         return ag->codegen->invalid_inst_src;
6713 
6714     bool is_volatile = asm_expr->volatile_token != 0;
6715     bool in_fn_scope = (scope_fn_entry(scope) != nullptr);
6716 
6717     if (!in_fn_scope) {
6718         if (is_volatile) {
6719             add_token_error(ag->codegen, node->owner, asm_expr->volatile_token,
6720                     buf_sprintf("volatile is meaningless on global assembly"));
6721             return ag->codegen->invalid_inst_src;
6722         }
6723 
6724         if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 ||
6725             asm_expr->clobber_list.length != 0)
6726         {
6727             add_node_error(ag->codegen, node,
6728                 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers"));
6729             return ag->codegen->invalid_inst_src;
6730         }
6731 
6732         return ir_build_asm_src(ag, scope, node, asm_template, nullptr, nullptr,
6733                                 nullptr, 0, is_volatile, true);
6734     }
6735 
6736     Stage1ZirInst **input_list = heap::c_allocator.allocate<Stage1ZirInst *>(asm_expr->input_list.length);
6737     Stage1ZirInst **output_types = heap::c_allocator.allocate<Stage1ZirInst *>(asm_expr->output_list.length);
6738     ZigVar **output_vars = heap::c_allocator.allocate<ZigVar *>(asm_expr->output_list.length);
6739     size_t return_count = 0;
6740     if (!is_volatile && asm_expr->output_list.length == 0) {
6741         add_node_error(ag->codegen, node,
6742                 buf_sprintf("assembly expression with no output must be marked volatile"));
6743         return ag->codegen->invalid_inst_src;
6744     }
6745     for (size_t i = 0; i < asm_expr->output_list.length; i += 1) {
6746         AsmOutput *asm_output = asm_expr->output_list.at(i);
6747         if (asm_output->return_type) {
6748             return_count += 1;
6749 
6750             Stage1ZirInst *return_type = astgen_node(ag, asm_output->return_type, scope);
6751             if (return_type == ag->codegen->invalid_inst_src)
6752                 return ag->codegen->invalid_inst_src;
6753             if (return_count > 1) {
6754                 add_node_error(ag->codegen, node,
6755                         buf_sprintf("inline assembly allows up to one output value"));
6756                 return ag->codegen->invalid_inst_src;
6757             }
6758             output_types[i] = return_type;
6759         } else {
6760             Buf *variable_name = asm_output->variable_name;
6761             // TODO there is some duplication here with astgen_identifier. I need to do a full audit of how
6762             // inline assembly works. https://github.com/ziglang/zig/issues/215
6763             ZigVar *var = find_variable(ag->codegen, scope, variable_name, nullptr);
6764             if (var) {
6765                 output_vars[i] = var;
6766             } else {
6767                 add_node_error(ag->codegen, node,
6768                         buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name)));
6769                 return ag->codegen->invalid_inst_src;
6770             }
6771         }
6772 
6773         const char modifier = *buf_ptr(asm_output->constraint);
6774         if (modifier != '=') {
6775             add_node_error(ag->codegen, node,
6776                 buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported."
6777                     " Compiler TODO: see https://github.com/ziglang/zig/issues/215",
6778                     buf_ptr(asm_output->asm_symbolic_name), modifier));
6779             return ag->codegen->invalid_inst_src;
6780         }
6781     }
6782     for (size_t i = 0; i < asm_expr->input_list.length; i += 1) {
6783         AsmInput *asm_input = asm_expr->input_list.at(i);
6784         Stage1ZirInst *input_value = astgen_node(ag, asm_input->expr, scope);
6785         if (input_value == ag->codegen->invalid_inst_src)
6786             return ag->codegen->invalid_inst_src;
6787 
6788         input_list[i] = input_value;
6789     }
6790 
6791     return ir_build_asm_src(ag, scope, node, asm_template, input_list, output_types,
6792                             output_vars, return_count, is_volatile, false);
6793 }
6794 
astgen_if_optional_expr(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)6795 static Stage1ZirInst *astgen_if_optional_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
6796         ResultLoc *result_loc)
6797 {
6798     assert(node->type == NodeTypeIfOptional);
6799 
6800     Buf *var_symbol = node->data.test_expr.var_symbol;
6801     AstNode *expr_node = node->data.test_expr.target_node;
6802     AstNode *then_node = node->data.test_expr.then_node;
6803     AstNode *else_node = node->data.test_expr.else_node;
6804     bool var_is_ptr = node->data.test_expr.var_is_ptr;
6805 
6806     ScopeExpr *spill_scope = create_expr_scope(ag->codegen, expr_node, scope);
6807     spill_scope->spill_harder = true;
6808 
6809     Stage1ZirInst *maybe_val_ptr = astgen_node_extra(ag, expr_node, &spill_scope->base, LValPtr, nullptr);
6810     if (maybe_val_ptr == ag->codegen->invalid_inst_src)
6811         return maybe_val_ptr;
6812 
6813     Stage1ZirInst *maybe_val = ir_build_load_ptr(ag, scope, node, maybe_val_ptr);
6814     Stage1ZirInst *is_non_null = ir_build_test_non_null_src(ag, scope, node, maybe_val);
6815 
6816     Stage1ZirBasicBlock *then_block = ir_create_basic_block(ag, scope, "OptionalThen");
6817     Stage1ZirBasicBlock *else_block = ir_create_basic_block(ag, scope, "OptionalElse");
6818     Stage1ZirBasicBlock *endif_block = ir_create_basic_block(ag, scope, "OptionalEndIf");
6819 
6820     Stage1ZirInst *is_comptime;
6821     if (ir_should_inline(ag->exec, scope)) {
6822         is_comptime = ir_build_const_bool(ag, scope, node, true);
6823     } else {
6824         is_comptime = ir_build_test_comptime(ag, scope, node, is_non_null);
6825     }
6826     Stage1ZirInst *cond_br_inst = ir_build_cond_br(ag, scope, node, is_non_null,
6827             then_block, else_block, is_comptime);
6828 
6829     ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(ag, cond_br_inst, else_block, endif_block,
6830             result_loc, is_comptime);
6831 
6832     ir_set_cursor_at_end_and_append_block(ag, then_block);
6833 
6834     Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, &spill_scope->base, is_comptime);
6835     Scope *var_scope;
6836     if (var_symbol) {
6837         bool is_shadowable = false;
6838         bool is_const = true;
6839         ZigVar *var = ir_create_var(ag, node, subexpr_scope,
6840                 var_symbol, is_const, is_const, is_shadowable, is_comptime);
6841 
6842         Stage1ZirInst *payload_ptr = ir_build_optional_unwrap_ptr(ag, subexpr_scope, node, maybe_val_ptr, false);
6843         Stage1ZirInst *var_value = var_is_ptr ?
6844             payload_ptr : ir_build_load_ptr(ag, &spill_scope->base, node, payload_ptr);
6845         build_decl_var_and_init(ag, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), is_comptime);
6846         var_scope = var->child_scope;
6847     } else {
6848         var_scope = subexpr_scope;
6849     }
6850     Stage1ZirInst *then_expr_result = astgen_node_extra(ag, then_node, var_scope, lval,
6851             &peer_parent->peers.at(0)->base);
6852     if (then_expr_result == ag->codegen->invalid_inst_src)
6853         return then_expr_result;
6854     Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
6855     if (!instr_is_unreachable(then_expr_result))
6856         ir_build_br(ag, scope, node, endif_block, is_comptime);
6857 
6858     ir_set_cursor_at_end_and_append_block(ag, else_block);
6859     Stage1ZirInst *else_expr_result;
6860     if (else_node) {
6861         else_expr_result = astgen_node_extra(ag, else_node, subexpr_scope, lval, &peer_parent->peers.at(1)->base);
6862         if (else_expr_result == ag->codegen->invalid_inst_src)
6863             return else_expr_result;
6864     } else {
6865         else_expr_result = ir_build_const_void(ag, scope, node);
6866         ir_build_end_expr(ag, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
6867     }
6868     Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6869     if (!instr_is_unreachable(else_expr_result))
6870         ir_build_br(ag, scope, node, endif_block, is_comptime);
6871 
6872     ir_set_cursor_at_end_and_append_block(ag, endif_block);
6873     Stage1ZirInst **incoming_values = heap::c_allocator.allocate<Stage1ZirInst *>(2);
6874     incoming_values[0] = then_expr_result;
6875     incoming_values[1] = else_expr_result;
6876     Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
6877     incoming_blocks[0] = after_then_block;
6878     incoming_blocks[1] = after_else_block;
6879 
6880     Stage1ZirInst *phi = ir_build_phi(ag, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
6881     return ir_expr_wrap(ag, scope, phi, result_loc);
6882 }
6883 
astgen_if_err_expr(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)6884 static Stage1ZirInst *astgen_if_err_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
6885         ResultLoc *result_loc)
6886 {
6887     assert(node->type == NodeTypeIfErrorExpr);
6888 
6889     AstNode *target_node = node->data.if_err_expr.target_node;
6890     AstNode *then_node = node->data.if_err_expr.then_node;
6891     AstNode *else_node = node->data.if_err_expr.else_node;
6892     bool var_is_ptr = node->data.if_err_expr.var_is_ptr;
6893     bool var_is_const = true;
6894     Buf *var_symbol = node->data.if_err_expr.var_symbol;
6895     Buf *err_symbol = node->data.if_err_expr.err_symbol;
6896 
6897     Stage1ZirInst *err_val_ptr = astgen_node_extra(ag, target_node, scope, LValPtr, nullptr);
6898     if (err_val_ptr == ag->codegen->invalid_inst_src)
6899         return err_val_ptr;
6900 
6901     Stage1ZirInst *err_val = ir_build_load_ptr(ag, scope, node, err_val_ptr);
6902     Stage1ZirInst *is_err = ir_build_test_err_src(ag, scope, node, err_val_ptr, true, false);
6903 
6904     Stage1ZirBasicBlock *ok_block = ir_create_basic_block(ag, scope, "TryOk");
6905     Stage1ZirBasicBlock *else_block = ir_create_basic_block(ag, scope, "TryElse");
6906     Stage1ZirBasicBlock *endif_block = ir_create_basic_block(ag, scope, "TryEnd");
6907 
6908     bool force_comptime = ir_should_inline(ag->exec, scope);
6909     Stage1ZirInst *is_comptime = force_comptime ? ir_build_const_bool(ag, scope, node, true) : ir_build_test_comptime(ag, scope, node, is_err);
6910     Stage1ZirInst *cond_br_inst = ir_build_cond_br(ag, scope, node, is_err, else_block, ok_block, is_comptime);
6911 
6912     ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(ag, cond_br_inst, else_block, endif_block,
6913             result_loc, is_comptime);
6914 
6915     ir_set_cursor_at_end_and_append_block(ag, ok_block);
6916 
6917     Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
6918     Scope *var_scope;
6919     if (var_symbol) {
6920         bool is_shadowable = false;
6921         Stage1ZirInst *var_is_comptime = force_comptime ? ir_build_const_bool(ag, subexpr_scope, node, true) : ir_build_test_comptime(ag, subexpr_scope, node, err_val);
6922         ZigVar *var = ir_create_var(ag, node, subexpr_scope,
6923                 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime);
6924 
6925         Stage1ZirInst *payload_ptr = ir_build_unwrap_err_payload_src(ag, subexpr_scope, node, err_val_ptr, false, false);
6926         Stage1ZirInst *var_value = var_is_ptr ?
6927             payload_ptr : ir_build_load_ptr(ag, subexpr_scope, node, payload_ptr);
6928         build_decl_var_and_init(ag, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), var_is_comptime);
6929         var_scope = var->child_scope;
6930     } else {
6931         var_scope = subexpr_scope;
6932     }
6933     Stage1ZirInst *then_expr_result = astgen_node_extra(ag, then_node, var_scope, lval,
6934             &peer_parent->peers.at(0)->base);
6935     if (then_expr_result == ag->codegen->invalid_inst_src)
6936         return then_expr_result;
6937     Stage1ZirBasicBlock *after_then_block = ag->current_basic_block;
6938     if (!instr_is_unreachable(then_expr_result))
6939         ir_build_br(ag, scope, node, endif_block, is_comptime);
6940 
6941     ir_set_cursor_at_end_and_append_block(ag, else_block);
6942 
6943     Stage1ZirInst *else_expr_result;
6944     if (else_node) {
6945         Scope *err_var_scope;
6946         if (err_symbol) {
6947             bool is_shadowable = false;
6948             bool is_const = true;
6949             ZigVar *var = ir_create_var(ag, node, subexpr_scope,
6950                     err_symbol, is_const, is_const, is_shadowable, is_comptime);
6951 
6952             Stage1ZirInst *err_ptr = ir_build_unwrap_err_code_src(ag, subexpr_scope, node, err_val_ptr);
6953             Stage1ZirInst *err_value = ir_build_load_ptr(ag, subexpr_scope, node, err_ptr);
6954             build_decl_var_and_init(ag, subexpr_scope, node, var, err_value, buf_ptr(err_symbol), is_comptime);
6955             err_var_scope = var->child_scope;
6956         } else {
6957             err_var_scope = subexpr_scope;
6958         }
6959         else_expr_result = astgen_node_extra(ag, else_node, err_var_scope, lval, &peer_parent->peers.at(1)->base);
6960         if (else_expr_result == ag->codegen->invalid_inst_src)
6961             return else_expr_result;
6962     } else {
6963         else_expr_result = ir_build_const_void(ag, scope, node);
6964         ir_build_end_expr(ag, scope, node, else_expr_result, &peer_parent->peers.at(1)->base);
6965     }
6966     Stage1ZirBasicBlock *after_else_block = ag->current_basic_block;
6967     if (!instr_is_unreachable(else_expr_result))
6968         ir_build_br(ag, scope, node, endif_block, is_comptime);
6969 
6970     ir_set_cursor_at_end_and_append_block(ag, endif_block);
6971     Stage1ZirInst **incoming_values = heap::c_allocator.allocate<Stage1ZirInst *>(2);
6972     incoming_values[0] = then_expr_result;
6973     incoming_values[1] = else_expr_result;
6974     Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
6975     incoming_blocks[0] = after_then_block;
6976     incoming_blocks[1] = after_else_block;
6977 
6978     Stage1ZirInst *phi = ir_build_phi(ag, scope, node, 2, incoming_blocks, incoming_values, peer_parent);
6979     return ir_expr_wrap(ag, scope, phi, result_loc);
6980 }
6981 
astgen_switch_prong_expr(Stage1AstGen * ag,Scope * scope,AstNode * switch_node,AstNode * prong_node,Stage1ZirBasicBlock * end_block,Stage1ZirInst * is_comptime,Stage1ZirInst * var_is_comptime,Stage1ZirInst * target_value_ptr,Stage1ZirInst ** prong_values,size_t prong_values_len,ZigList<Stage1ZirBasicBlock * > * incoming_blocks,ZigList<Stage1ZirInst * > * incoming_values,Stage1ZirInstSwitchElseVar ** out_switch_else_var,LVal lval,ResultLoc * result_loc)6982 static bool astgen_switch_prong_expr(Stage1AstGen *ag, Scope *scope, AstNode *switch_node, AstNode *prong_node,
6983         Stage1ZirBasicBlock *end_block, Stage1ZirInst *is_comptime, Stage1ZirInst *var_is_comptime,
6984         Stage1ZirInst *target_value_ptr, Stage1ZirInst **prong_values, size_t prong_values_len,
6985         ZigList<Stage1ZirBasicBlock *> *incoming_blocks, ZigList<Stage1ZirInst *> *incoming_values,
6986         Stage1ZirInstSwitchElseVar **out_switch_else_var, LVal lval, ResultLoc *result_loc)
6987 {
6988     assert(switch_node->type == NodeTypeSwitchExpr);
6989     assert(prong_node->type == NodeTypeSwitchProng);
6990 
6991     AstNode *expr_node = prong_node->data.switch_prong.expr;
6992     AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol;
6993     Scope *child_scope;
6994     if (var_symbol_node) {
6995         assert(var_symbol_node->type == NodeTypeIdentifier);
6996         Buf *var_name = node_identifier_buf(var_symbol_node);
6997         bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr;
6998 
6999         bool is_shadowable = false;
7000         bool is_const = true;
7001         ZigVar *var = ir_create_var(ag, var_symbol_node, scope,
7002                 var_name, is_const, is_const, is_shadowable, var_is_comptime);
7003         child_scope = var->child_scope;
7004         Stage1ZirInst *var_value;
7005         if (out_switch_else_var != nullptr) {
7006             Stage1ZirInstSwitchElseVar *switch_else_var = ir_build_switch_else_var(ag, scope, var_symbol_node,
7007                     target_value_ptr);
7008             *out_switch_else_var = switch_else_var;
7009             Stage1ZirInst *payload_ptr = &switch_else_var->base;
7010             var_value = var_is_ptr ?
7011                 payload_ptr : ir_build_load_ptr(ag, scope, var_symbol_node, payload_ptr);
7012         } else if (prong_values != nullptr) {
7013             Stage1ZirInst *payload_ptr = ir_build_switch_var(ag, scope, var_symbol_node, target_value_ptr,
7014                     prong_values, prong_values_len);
7015             var_value = var_is_ptr ?
7016                 payload_ptr : ir_build_load_ptr(ag, scope, var_symbol_node, payload_ptr);
7017         } else {
7018             var_value = var_is_ptr ?
7019                 target_value_ptr : ir_build_load_ptr(ag, scope, var_symbol_node, target_value_ptr);
7020         }
7021         build_decl_var_and_init(ag, scope, var_symbol_node, var, var_value, buf_ptr(var_name), var_is_comptime);
7022     } else {
7023         child_scope = scope;
7024     }
7025 
7026     Stage1ZirInst *expr_result = astgen_node_extra(ag, expr_node, child_scope, lval, result_loc);
7027     if (expr_result == ag->codegen->invalid_inst_src)
7028         return false;
7029     if (!instr_is_unreachable(expr_result))
7030         ir_build_br(ag, scope, switch_node, end_block, is_comptime);
7031     incoming_blocks->append(ag->current_basic_block);
7032     incoming_values->append(expr_result);
7033     return true;
7034 }
7035 
astgen_switch_expr(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)7036 static Stage1ZirInst *astgen_switch_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
7037         ResultLoc *result_loc)
7038 {
7039     assert(node->type == NodeTypeSwitchExpr);
7040 
7041     AstNode *target_node = node->data.switch_expr.expr;
7042     Stage1ZirInst *target_value_ptr = astgen_node_extra(ag, target_node, scope, LValPtr, nullptr);
7043     if (target_value_ptr == ag->codegen->invalid_inst_src)
7044         return target_value_ptr;
7045     Stage1ZirInst *target_value = ir_build_switch_target(ag, scope, node, target_value_ptr);
7046 
7047     Stage1ZirBasicBlock *else_block = ir_create_basic_block(ag, scope, "SwitchElse");
7048     Stage1ZirBasicBlock *end_block = ir_create_basic_block(ag, scope, "SwitchEnd");
7049 
7050     size_t prong_count = node->data.switch_expr.prongs.length;
7051     ZigList<Stage1ZirInstSwitchBrCase> cases = {0};
7052 
7053     Stage1ZirInst *is_comptime;
7054     Stage1ZirInst *var_is_comptime;
7055     if (ir_should_inline(ag->exec, scope)) {
7056         is_comptime = ir_build_const_bool(ag, scope, node, true);
7057         var_is_comptime = is_comptime;
7058     } else {
7059         is_comptime = ir_build_test_comptime(ag, scope, node, target_value);
7060         var_is_comptime = ir_build_test_comptime(ag, scope, node, target_value_ptr);
7061     }
7062 
7063     ZigList<Stage1ZirInst *> incoming_values = {0};
7064     ZigList<Stage1ZirBasicBlock *> incoming_blocks = {0};
7065     ZigList<Stage1ZirInstCheckSwitchProngsRange> check_ranges = {0};
7066 
7067     Stage1ZirInstSwitchElseVar *switch_else_var = nullptr;
7068 
7069     ResultLocPeerParent *peer_parent = heap::c_allocator.create<ResultLocPeerParent>();
7070     peer_parent->base.id = ResultLocIdPeerParent;
7071     peer_parent->base.allow_write_through_const = result_loc->allow_write_through_const;
7072     peer_parent->end_bb = end_block;
7073     peer_parent->is_comptime = is_comptime;
7074     peer_parent->parent = result_loc;
7075 
7076     ir_build_reset_result(ag, scope, node, &peer_parent->base);
7077 
7078     // First do the else and the ranges
7079     Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, scope, is_comptime);
7080     Scope *comptime_scope = create_comptime_scope(ag->codegen, node, scope);
7081     AstNode *else_prong = nullptr;
7082     AstNode *underscore_prong = nullptr;
7083     for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {
7084         AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
7085         size_t prong_item_count = prong_node->data.switch_prong.items.length;
7086         if (prong_node->data.switch_prong.any_items_are_range) {
7087             ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
7088 
7089             Stage1ZirInst *ok_bit = nullptr;
7090             AstNode *last_item_node = nullptr;
7091             for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
7092                 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
7093                 last_item_node = item_node;
7094                 if (item_node->type == NodeTypeSwitchRange) {
7095                     AstNode *start_node = item_node->data.switch_range.start;
7096                     AstNode *end_node = item_node->data.switch_range.end;
7097 
7098                     Stage1ZirInst *start_value = astgen_node(ag, start_node, comptime_scope);
7099                     if (start_value == ag->codegen->invalid_inst_src)
7100                         return ag->codegen->invalid_inst_src;
7101 
7102                     Stage1ZirInst *end_value = astgen_node(ag, end_node, comptime_scope);
7103                     if (end_value == ag->codegen->invalid_inst_src)
7104                         return ag->codegen->invalid_inst_src;
7105 
7106                     Stage1ZirInstCheckSwitchProngsRange *check_range = check_ranges.add_one();
7107                     check_range->start = start_value;
7108                     check_range->end = end_value;
7109 
7110                     Stage1ZirInst *lower_range_ok = ir_build_bin_op(ag, scope, item_node, IrBinOpCmpGreaterOrEq,
7111                             target_value, start_value, false);
7112                     Stage1ZirInst *upper_range_ok = ir_build_bin_op(ag, scope, item_node, IrBinOpCmpLessOrEq,
7113                             target_value, end_value, false);
7114                     Stage1ZirInst *both_ok = ir_build_bin_op(ag, scope, item_node, IrBinOpBoolAnd,
7115                             lower_range_ok, upper_range_ok, false);
7116                     if (ok_bit) {
7117                         ok_bit = ir_build_bin_op(ag, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false);
7118                     } else {
7119                         ok_bit = both_ok;
7120                     }
7121                 } else {
7122                     Stage1ZirInst *item_value = astgen_node(ag, item_node, comptime_scope);
7123                     if (item_value == ag->codegen->invalid_inst_src)
7124                         return ag->codegen->invalid_inst_src;
7125 
7126                     Stage1ZirInstCheckSwitchProngsRange *check_range = check_ranges.add_one();
7127                     check_range->start = item_value;
7128                     check_range->end = item_value;
7129 
7130                     Stage1ZirInst *cmp_ok = ir_build_bin_op(ag, scope, item_node, IrBinOpCmpEq,
7131                             item_value, target_value, false);
7132                     if (ok_bit) {
7133                         ok_bit = ir_build_bin_op(ag, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false);
7134                     } else {
7135                         ok_bit = cmp_ok;
7136                     }
7137                 }
7138             }
7139 
7140             Stage1ZirBasicBlock *range_block_yes = ir_create_basic_block(ag, scope, "SwitchRangeYes");
7141             Stage1ZirBasicBlock *range_block_no = ir_create_basic_block(ag, scope, "SwitchRangeNo");
7142 
7143             assert(ok_bit);
7144             assert(last_item_node);
7145             Stage1ZirInst *br_inst = ir_build_cond_br(ag, scope, last_item_node, ok_bit,
7146                         range_block_yes, range_block_no, is_comptime);
7147             if (peer_parent->base.source_instruction == nullptr) {
7148                 peer_parent->base.source_instruction = br_inst;
7149             }
7150 
7151             if (peer_parent->peers.length > 0) {
7152                 peer_parent->peers.last()->next_bb = range_block_yes;
7153             }
7154             peer_parent->peers.append(this_peer_result_loc);
7155             ir_set_cursor_at_end_and_append_block(ag, range_block_yes);
7156             if (!astgen_switch_prong_expr(ag, subexpr_scope, node, prong_node, end_block,
7157                 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0,
7158                 &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base))
7159             {
7160                 return ag->codegen->invalid_inst_src;
7161             }
7162 
7163             ir_set_cursor_at_end_and_append_block(ag, range_block_no);
7164         } else {
7165             if (prong_item_count == 0) {
7166                 if (else_prong) {
7167                     ErrorMsg *msg = add_node_error(ag->codegen, prong_node,
7168                             buf_sprintf("multiple else prongs in switch expression"));
7169                     add_error_note(ag->codegen, msg, else_prong,
7170                             buf_sprintf("previous else prong here"));
7171                     return ag->codegen->invalid_inst_src;
7172                 }
7173                 else_prong = prong_node;
7174             } else if (prong_item_count == 1 &&
7175                     prong_node->data.switch_prong.items.at(0)->type == NodeTypeIdentifier &&
7176                     buf_eql_str(node_identifier_buf(prong_node->data.switch_prong.items.at(0)), "_")) {
7177                 if (underscore_prong) {
7178                     ErrorMsg *msg = add_node_error(ag->codegen, prong_node,
7179                             buf_sprintf("multiple '_' prongs in switch expression"));
7180                     add_error_note(ag->codegen, msg, underscore_prong,
7181                             buf_sprintf("previous '_' prong here"));
7182                     return ag->codegen->invalid_inst_src;
7183                 }
7184                 underscore_prong = prong_node;
7185             } else {
7186                 continue;
7187             }
7188            if (underscore_prong && else_prong) {
7189                 ErrorMsg *msg = add_node_error(ag->codegen, prong_node,
7190                         buf_sprintf("else and '_' prong in switch expression"));
7191                 if (underscore_prong == prong_node)
7192                     add_error_note(ag->codegen, msg, else_prong,
7193                             buf_sprintf("else prong here"));
7194                 else
7195                     add_error_note(ag->codegen, msg, underscore_prong,
7196                             buf_sprintf("'_' prong here"));
7197                 return ag->codegen->invalid_inst_src;
7198             }
7199             ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
7200 
7201             Stage1ZirBasicBlock *prev_block = ag->current_basic_block;
7202             if (peer_parent->peers.length > 0) {
7203                 peer_parent->peers.last()->next_bb = else_block;
7204             }
7205             peer_parent->peers.append(this_peer_result_loc);
7206             ir_set_cursor_at_end_and_append_block(ag, else_block);
7207             if (!astgen_switch_prong_expr(ag, subexpr_scope, node, prong_node, end_block,
7208                 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values,
7209                 &switch_else_var, LValNone, &this_peer_result_loc->base))
7210             {
7211                 return ag->codegen->invalid_inst_src;
7212             }
7213             ir_set_cursor_at_end(ag, prev_block);
7214         }
7215     }
7216 
7217     // next do the non-else non-ranges
7218     for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) {
7219         AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
7220         size_t prong_item_count = prong_node->data.switch_prong.items.length;
7221         if (prong_item_count == 0)
7222             continue;
7223         if (prong_node->data.switch_prong.any_items_are_range)
7224             continue;
7225         if (underscore_prong == prong_node)
7226             continue;
7227 
7228         ResultLocPeer *this_peer_result_loc = create_peer_result(peer_parent);
7229 
7230         Stage1ZirBasicBlock *prong_block = ir_create_basic_block(ag, scope, "SwitchProng");
7231         Stage1ZirInst **items = heap::c_allocator.allocate<Stage1ZirInst *>(prong_item_count);
7232 
7233         for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) {
7234             AstNode *item_node = prong_node->data.switch_prong.items.at(item_i);
7235             assert(item_node->type != NodeTypeSwitchRange);
7236 
7237             Stage1ZirInst *item_value = astgen_node(ag, item_node, comptime_scope);
7238             if (item_value == ag->codegen->invalid_inst_src)
7239                 return ag->codegen->invalid_inst_src;
7240 
7241             Stage1ZirInstCheckSwitchProngsRange *check_range = check_ranges.add_one();
7242             check_range->start = item_value;
7243             check_range->end = item_value;
7244 
7245             Stage1ZirInstSwitchBrCase *this_case = cases.add_one();
7246             this_case->value = item_value;
7247             this_case->block = prong_block;
7248 
7249             items[item_i] = item_value;
7250         }
7251 
7252         Stage1ZirBasicBlock *prev_block = ag->current_basic_block;
7253         if (peer_parent->peers.length > 0) {
7254             peer_parent->peers.last()->next_bb = prong_block;
7255         }
7256         peer_parent->peers.append(this_peer_result_loc);
7257         ir_set_cursor_at_end_and_append_block(ag, prong_block);
7258         if (!astgen_switch_prong_expr(ag, subexpr_scope, node, prong_node, end_block,
7259             is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count,
7260             &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base))
7261         {
7262             return ag->codegen->invalid_inst_src;
7263         }
7264 
7265         ir_set_cursor_at_end(ag, prev_block);
7266 
7267     }
7268 
7269     Stage1ZirInst *switch_prongs_void = ir_build_check_switch_prongs(ag, scope, node, target_value,
7270             check_ranges.items, check_ranges.length, else_prong, underscore_prong != nullptr);
7271 
7272     Stage1ZirInst *br_instruction;
7273     if (cases.length == 0) {
7274         br_instruction = ir_build_br(ag, scope, node, else_block, is_comptime);
7275     } else {
7276         Stage1ZirInstSwitchBr *switch_br = ir_build_switch_br_src(ag, scope, node, target_value, else_block,
7277                 cases.length, cases.items, is_comptime, switch_prongs_void);
7278         if (switch_else_var != nullptr) {
7279             switch_else_var->switch_br = switch_br;
7280         }
7281         br_instruction = &switch_br->base;
7282     }
7283     if (peer_parent->base.source_instruction == nullptr) {
7284         peer_parent->base.source_instruction = br_instruction;
7285     }
7286     for (size_t i = 0; i < peer_parent->peers.length; i += 1) {
7287         peer_parent->peers.at(i)->base.source_instruction = peer_parent->base.source_instruction;
7288     }
7289 
7290     if (!else_prong && !underscore_prong) {
7291         if (peer_parent->peers.length != 0) {
7292             peer_parent->peers.last()->next_bb = else_block;
7293         }
7294         ir_set_cursor_at_end_and_append_block(ag, else_block);
7295         ir_build_unreachable(ag, scope, node);
7296     } else {
7297         if (peer_parent->peers.length != 0) {
7298             peer_parent->peers.last()->next_bb = end_block;
7299         }
7300     }
7301 
7302     ir_set_cursor_at_end_and_append_block(ag, end_block);
7303     assert(incoming_blocks.length == incoming_values.length);
7304     Stage1ZirInst *result_instruction;
7305     if (incoming_blocks.length == 0) {
7306         result_instruction = ir_build_const_void(ag, scope, node);
7307     } else {
7308         result_instruction = ir_build_phi(ag, scope, node, incoming_blocks.length,
7309                 incoming_blocks.items, incoming_values.items, peer_parent);
7310     }
7311     return ir_lval_wrap(ag, scope, result_instruction, lval, result_loc);
7312 }
7313 
astgen_comptime(Stage1AstGen * ag,Scope * parent_scope,AstNode * node,LVal lval)7314 static Stage1ZirInst *astgen_comptime(Stage1AstGen *ag, Scope *parent_scope, AstNode *node, LVal lval) {
7315     assert(node->type == NodeTypeCompTime);
7316 
7317     Scope *child_scope = create_comptime_scope(ag->codegen, node, parent_scope);
7318     // purposefully pass null for result_loc and let EndExpr handle it
7319     return astgen_node_extra(ag, node->data.comptime_expr.expr, child_scope, lval, nullptr);
7320 }
7321 
astgen_nosuspend(Stage1AstGen * ag,Scope * parent_scope,AstNode * node,LVal lval)7322 static Stage1ZirInst *astgen_nosuspend(Stage1AstGen *ag, Scope *parent_scope, AstNode *node, LVal lval) {
7323     assert(node->type == NodeTypeNoSuspend);
7324 
7325     Scope *child_scope = create_nosuspend_scope(ag->codegen, node, parent_scope);
7326     // purposefully pass null for result_loc and let EndExpr handle it
7327     return astgen_node_extra(ag, node->data.nosuspend_expr.expr, child_scope, lval, nullptr);
7328 }
7329 
astgen_return_from_block(Stage1AstGen * ag,Scope * break_scope,AstNode * node,ScopeBlock * block_scope)7330 static Stage1ZirInst *astgen_return_from_block(Stage1AstGen *ag, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) {
7331     Stage1ZirInst *is_comptime;
7332     if (ir_should_inline(ag->exec, break_scope)) {
7333         is_comptime = ir_build_const_bool(ag, break_scope, node, true);
7334     } else {
7335         is_comptime = block_scope->is_comptime;
7336     }
7337 
7338     Stage1ZirInst *result_value;
7339     if (node->data.break_expr.expr) {
7340         ResultLocPeer *peer_result = create_peer_result(block_scope->peer_parent);
7341         block_scope->peer_parent->peers.append(peer_result);
7342 
7343         result_value = astgen_node_extra(ag, node->data.break_expr.expr, break_scope, block_scope->lval,
7344                 &peer_result->base);
7345         if (result_value == ag->codegen->invalid_inst_src)
7346             return ag->codegen->invalid_inst_src;
7347     } else {
7348         result_value = ir_build_const_void(ag, break_scope, node);
7349     }
7350 
7351     Stage1ZirBasicBlock *dest_block = block_scope->end_block;
7352     if (!astgen_defers_for_block(ag, break_scope, dest_block->scope, nullptr, nullptr))
7353         return ag->codegen->invalid_inst_src;
7354 
7355     block_scope->incoming_blocks->append(ag->current_basic_block);
7356     block_scope->incoming_values->append(result_value);
7357     return ir_build_br(ag, break_scope, node, dest_block, is_comptime);
7358 }
7359 
astgen_break(Stage1AstGen * ag,Scope * break_scope,AstNode * node)7360 static Stage1ZirInst *astgen_break(Stage1AstGen *ag, Scope *break_scope, AstNode *node) {
7361     assert(node->type == NodeTypeBreak);
7362 
7363     // Search up the scope. We'll find one of these things first:
7364     // * function definition scope or global scope => error, break outside loop
7365     // * defer expression scope => error, cannot break out of defer expression
7366     // * loop scope => OK
7367     // * (if it's a labeled break) labeled block => OK
7368 
7369     Scope *search_scope = break_scope;
7370     ScopeLoop *loop_scope;
7371     for (;;) {
7372         if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) {
7373             if (node->data.break_expr.name != nullptr) {
7374                 add_node_error(ag->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name)));
7375                 return ag->codegen->invalid_inst_src;
7376             } else {
7377                 add_node_error(ag->codegen, node, buf_sprintf("break expression outside loop"));
7378                 return ag->codegen->invalid_inst_src;
7379             }
7380         } else if (search_scope->id == ScopeIdDeferExpr) {
7381             add_node_error(ag->codegen, node, buf_sprintf("cannot break out of defer expression"));
7382             return ag->codegen->invalid_inst_src;
7383         } else if (search_scope->id == ScopeIdLoop) {
7384             ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope;
7385             if (node->data.break_expr.name == nullptr ||
7386                 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name)))
7387             {
7388                 this_loop_scope->name_used = true;
7389                 loop_scope = this_loop_scope;
7390                 break;
7391             }
7392         } else if (search_scope->id == ScopeIdBlock) {
7393             ScopeBlock *this_block_scope = (ScopeBlock *)search_scope;
7394             if (node->data.break_expr.name != nullptr &&
7395                 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name)))
7396             {
7397                 assert(this_block_scope->end_block != nullptr);
7398                 this_block_scope->name_used = true;
7399                 return astgen_return_from_block(ag, break_scope, node, this_block_scope);
7400             }
7401         } else if (search_scope->id == ScopeIdSuspend) {
7402             add_node_error(ag->codegen, node, buf_sprintf("cannot break out of suspend block"));
7403             return ag->codegen->invalid_inst_src;
7404         }
7405         search_scope = search_scope->parent;
7406     }
7407 
7408     Stage1ZirInst *is_comptime;
7409     if (ir_should_inline(ag->exec, break_scope)) {
7410         is_comptime = ir_build_const_bool(ag, break_scope, node, true);
7411     } else {
7412         is_comptime = loop_scope->is_comptime;
7413     }
7414 
7415     Stage1ZirInst *result_value;
7416     if (node->data.break_expr.expr) {
7417         ResultLocPeer *peer_result = create_peer_result(loop_scope->peer_parent);
7418         loop_scope->peer_parent->peers.append(peer_result);
7419 
7420         result_value = astgen_node_extra(ag, node->data.break_expr.expr, break_scope,
7421                 loop_scope->lval, &peer_result->base);
7422         if (result_value == ag->codegen->invalid_inst_src)
7423             return ag->codegen->invalid_inst_src;
7424     } else {
7425         result_value = ir_build_const_void(ag, break_scope, node);
7426     }
7427 
7428     Stage1ZirBasicBlock *dest_block = loop_scope->break_block;
7429     if (!astgen_defers_for_block(ag, break_scope, dest_block->scope, nullptr, nullptr))
7430         return ag->codegen->invalid_inst_src;
7431 
7432     loop_scope->incoming_blocks->append(ag->current_basic_block);
7433     loop_scope->incoming_values->append(result_value);
7434     return ir_build_br(ag, break_scope, node, dest_block, is_comptime);
7435 }
7436 
astgen_continue(Stage1AstGen * ag,Scope * continue_scope,AstNode * node)7437 static Stage1ZirInst *astgen_continue(Stage1AstGen *ag, Scope *continue_scope, AstNode *node) {
7438     assert(node->type == NodeTypeContinue);
7439 
7440     // Search up the scope. We'll find one of these things first:
7441     // * function definition scope or global scope => error, break outside loop
7442     // * defer expression scope => error, cannot break out of defer expression
7443     // * loop scope => OK
7444 
7445     ZigList<ScopeRuntime *> runtime_scopes = {};
7446 
7447     Scope *search_scope = continue_scope;
7448     ScopeLoop *loop_scope;
7449     for (;;) {
7450         if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) {
7451             if (node->data.continue_expr.name != nullptr) {
7452                 add_node_error(ag->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name)));
7453                 return ag->codegen->invalid_inst_src;
7454             } else {
7455                 add_node_error(ag->codegen, node, buf_sprintf("continue expression outside loop"));
7456                 return ag->codegen->invalid_inst_src;
7457             }
7458         } else if (search_scope->id == ScopeIdDeferExpr) {
7459             add_node_error(ag->codegen, node, buf_sprintf("cannot continue out of defer expression"));
7460             return ag->codegen->invalid_inst_src;
7461         } else if (search_scope->id == ScopeIdLoop) {
7462             ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope;
7463             if (node->data.continue_expr.name == nullptr ||
7464                 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name)))
7465             {
7466                 this_loop_scope->name_used = true;
7467                 loop_scope = this_loop_scope;
7468                 break;
7469             }
7470         } else if (search_scope->id == ScopeIdRuntime) {
7471             ScopeRuntime *scope_runtime = (ScopeRuntime *)search_scope;
7472             runtime_scopes.append(scope_runtime);
7473         }
7474         search_scope = search_scope->parent;
7475     }
7476 
7477     Stage1ZirInst *is_comptime;
7478     if (ir_should_inline(ag->exec, continue_scope)) {
7479         is_comptime = ir_build_const_bool(ag, continue_scope, node, true);
7480     } else {
7481         is_comptime = loop_scope->is_comptime;
7482     }
7483 
7484     for (size_t i = 0; i < runtime_scopes.length; i += 1) {
7485         ScopeRuntime *scope_runtime = runtime_scopes.at(i);
7486         ir_build_check_runtime_scope(ag, continue_scope, node, scope_runtime->is_comptime, is_comptime);
7487     }
7488     runtime_scopes.deinit();
7489 
7490     Stage1ZirBasicBlock *dest_block = loop_scope->continue_block;
7491     if (!astgen_defers_for_block(ag, continue_scope, dest_block->scope, nullptr, nullptr))
7492         return ag->codegen->invalid_inst_src;
7493     return ir_build_br(ag, continue_scope, node, dest_block, is_comptime);
7494 }
7495 
astgen_error_type(Stage1AstGen * ag,Scope * scope,AstNode * node)7496 static Stage1ZirInst *astgen_error_type(Stage1AstGen *ag, Scope *scope, AstNode *node) {
7497     assert(node->type == NodeTypeErrorType);
7498     return ir_build_const_type(ag, scope, node, ag->codegen->builtin_types.entry_global_error_set);
7499 }
7500 
astgen_defer(Stage1AstGen * ag,Scope * parent_scope,AstNode * node)7501 static Stage1ZirInst *astgen_defer(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
7502     assert(node->type == NodeTypeDefer);
7503 
7504     ScopeDefer *defer_child_scope = create_defer_scope(ag->codegen, node, parent_scope);
7505     node->data.defer.child_scope = &defer_child_scope->base;
7506 
7507     ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(ag->codegen, node, parent_scope);
7508     node->data.defer.expr_scope = &defer_expr_scope->base;
7509 
7510     return ir_build_const_void(ag, parent_scope, node);
7511 }
7512 
astgen_slice(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)7513 static Stage1ZirInst *astgen_slice(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) {
7514     assert(node->type == NodeTypeSliceExpr);
7515 
7516     AstNodeSliceExpr *slice_expr = &node->data.slice_expr;
7517     AstNode *array_node = slice_expr->array_ref_expr;
7518     AstNode *start_node = slice_expr->start;
7519     AstNode *end_node = slice_expr->end;
7520     AstNode *sentinel_node = slice_expr->sentinel;
7521 
7522     Stage1ZirInst *ptr_value = astgen_node_extra(ag, array_node, scope, LValPtr, nullptr);
7523     if (ptr_value == ag->codegen->invalid_inst_src)
7524         return ag->codegen->invalid_inst_src;
7525 
7526     Stage1ZirInst *start_value = astgen_node(ag, start_node, scope);
7527     if (start_value == ag->codegen->invalid_inst_src)
7528         return ag->codegen->invalid_inst_src;
7529 
7530     Stage1ZirInst *end_value;
7531     if (end_node) {
7532         end_value = astgen_node(ag, end_node, scope);
7533         if (end_value == ag->codegen->invalid_inst_src)
7534             return ag->codegen->invalid_inst_src;
7535     } else {
7536         end_value = nullptr;
7537     }
7538 
7539     Stage1ZirInst *sentinel_value;
7540     if (sentinel_node) {
7541         sentinel_value = astgen_node(ag, sentinel_node, scope);
7542         if (sentinel_value == ag->codegen->invalid_inst_src)
7543             return ag->codegen->invalid_inst_src;
7544     } else {
7545         sentinel_value = nullptr;
7546     }
7547 
7548     Stage1ZirInst *slice = ir_build_slice_src(ag, scope, node, ptr_value, start_value, end_value,
7549             sentinel_value, true, result_loc);
7550     return ir_lval_wrap(ag, scope, slice, lval, result_loc);
7551 }
7552 
astgen_catch(Stage1AstGen * ag,Scope * parent_scope,AstNode * node,LVal lval,ResultLoc * result_loc)7553 static Stage1ZirInst *astgen_catch(Stage1AstGen *ag, Scope *parent_scope, AstNode *node, LVal lval,
7554         ResultLoc *result_loc)
7555 {
7556     assert(node->type == NodeTypeCatchExpr);
7557 
7558     AstNode *op1_node = node->data.unwrap_err_expr.op1;
7559     AstNode *op2_node = node->data.unwrap_err_expr.op2;
7560     AstNode *var_node = node->data.unwrap_err_expr.symbol;
7561 
7562     if (op2_node->type == NodeTypeUnreachable) {
7563         if (var_node != nullptr) {
7564             assert(var_node->type == NodeTypeIdentifier);
7565             Buf *var_name = node_identifier_buf(var_node);
7566             add_node_error(ag->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name)));
7567             return ag->codegen->invalid_inst_src;
7568         }
7569         return astgen_catch_unreachable(ag, parent_scope, node, op1_node, lval, result_loc);
7570     }
7571 
7572 
7573     ScopeExpr *spill_scope = create_expr_scope(ag->codegen, op1_node, parent_scope);
7574     spill_scope->spill_harder = true;
7575 
7576     Stage1ZirInst *err_union_ptr = astgen_node_extra(ag, op1_node, &spill_scope->base, LValPtr, nullptr);
7577     if (err_union_ptr == ag->codegen->invalid_inst_src)
7578         return ag->codegen->invalid_inst_src;
7579 
7580     Stage1ZirInst *is_err = ir_build_test_err_src(ag, parent_scope, node, err_union_ptr, true, false);
7581 
7582     Stage1ZirInst *is_comptime;
7583     if (ir_should_inline(ag->exec, parent_scope)) {
7584         is_comptime = ir_build_const_bool(ag, parent_scope, node, true);
7585     } else {
7586         is_comptime = ir_build_test_comptime(ag, parent_scope, node, is_err);
7587     }
7588 
7589     Stage1ZirBasicBlock *ok_block = ir_create_basic_block(ag, parent_scope, "UnwrapErrOk");
7590     Stage1ZirBasicBlock *err_block = ir_create_basic_block(ag, parent_scope, "UnwrapErrError");
7591     Stage1ZirBasicBlock *end_block = ir_create_basic_block(ag, parent_scope, "UnwrapErrEnd");
7592     Stage1ZirInst *cond_br_inst = ir_build_cond_br(ag, parent_scope, node, is_err, err_block, ok_block, is_comptime);
7593 
7594     ResultLocPeerParent *peer_parent = ir_build_binary_result_peers(ag, cond_br_inst, ok_block, end_block, result_loc,
7595             is_comptime);
7596 
7597     ir_set_cursor_at_end_and_append_block(ag, err_block);
7598     Scope *subexpr_scope = create_runtime_scope(ag->codegen, node, &spill_scope->base, is_comptime);
7599     Scope *err_scope;
7600     if (var_node) {
7601         assert(var_node->type == NodeTypeIdentifier);
7602         Buf *var_name = node_identifier_buf(var_node);
7603         bool is_const = true;
7604         bool is_shadowable = false;
7605         ZigVar *var = ir_create_var(ag, node, subexpr_scope, var_name,
7606             is_const, is_const, is_shadowable, is_comptime);
7607         err_scope = var->child_scope;
7608         Stage1ZirInst *err_ptr = ir_build_unwrap_err_code_src(ag, err_scope, node, err_union_ptr);
7609         Stage1ZirInst *err_value = ir_build_load_ptr(ag, err_scope, var_node, err_ptr);
7610         build_decl_var_and_init(ag, err_scope, var_node, var, err_value, buf_ptr(var_name), is_comptime);
7611     } else {
7612         err_scope = subexpr_scope;
7613     }
7614     Stage1ZirInst *err_result = astgen_node_extra(ag, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base);
7615     if (err_result == ag->codegen->invalid_inst_src)
7616         return ag->codegen->invalid_inst_src;
7617     Stage1ZirBasicBlock *after_err_block = ag->current_basic_block;
7618     if (!instr_is_unreachable(err_result))
7619         ir_build_br(ag, parent_scope, node, end_block, is_comptime);
7620 
7621     ir_set_cursor_at_end_and_append_block(ag, ok_block);
7622     Stage1ZirInst *unwrapped_ptr = ir_build_unwrap_err_payload_src(ag, parent_scope, node, err_union_ptr, false, false);
7623     Stage1ZirInst *unwrapped_payload = ir_build_load_ptr(ag, parent_scope, node, unwrapped_ptr);
7624     ir_build_end_expr(ag, parent_scope, node, unwrapped_payload, &peer_parent->peers.at(1)->base);
7625     Stage1ZirBasicBlock *after_ok_block = ag->current_basic_block;
7626     ir_build_br(ag, parent_scope, node, end_block, is_comptime);
7627 
7628     ir_set_cursor_at_end_and_append_block(ag, end_block);
7629     Stage1ZirInst **incoming_values = heap::c_allocator.allocate<Stage1ZirInst *>(2);
7630     incoming_values[0] = err_result;
7631     incoming_values[1] = unwrapped_payload;
7632     Stage1ZirBasicBlock **incoming_blocks = heap::c_allocator.allocate<Stage1ZirBasicBlock *>(2);
7633     incoming_blocks[0] = after_err_block;
7634     incoming_blocks[1] = after_ok_block;
7635     Stage1ZirInst *phi = ir_build_phi(ag, parent_scope, node, 2, incoming_blocks, incoming_values, peer_parent);
7636     return ir_lval_wrap(ag, parent_scope, phi, lval, result_loc);
7637 }
7638 
render_instance_name_recursive(CodeGen * codegen,Buf * name,Scope * outer_scope,Scope * inner_scope)7639 static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) {
7640     if (inner_scope == nullptr || inner_scope == outer_scope) return false;
7641     bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent);
7642     if (inner_scope->id != ScopeIdVarDecl)
7643         return need_comma;
7644 
7645     ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope;
7646     if (need_comma)
7647         buf_append_char(name, ',');
7648     // TODO: const ptr reinterpret here to make the var type agree with the value?
7649     render_const_value(codegen, name, var_scope->var->const_value);
7650     return true;
7651 }
7652 
get_anon_type_name(CodeGen * codegen,Stage1Zir * exec,const char * kind_name,Scope * scope,AstNode * source_node,Buf * out_bare_name,ResultLoc * result_loc)7653 Buf *get_anon_type_name(CodeGen *codegen, Stage1Zir *exec, const char *kind_name,
7654         Scope *scope, AstNode *source_node, Buf *out_bare_name, ResultLoc *result_loc)
7655 {
7656     // See https://ziglang.org/documentation/master/#Struct-Naming .
7657     bool force_generic = false;
7658     if (result_loc != nullptr
7659         && result_loc->source_instruction != nullptr
7660         && result_loc->source_instruction->source_node != nullptr
7661     ) {
7662         switch (result_loc->source_instruction->source_node->type) {
7663             case NodeTypeVariableDeclaration: {
7664                     ZigType *import = get_scope_import(scope);
7665                     Buf *name = buf_alloc();
7666                     append_namespace_qualification(codegen, name, import);
7667                     const auto &basename = result_loc->source_instruction->source_node->data.variable_declaration.symbol;
7668                     buf_append_buf(name, basename);
7669                     buf_init_from_buf(out_bare_name, basename);
7670                     return name;
7671                 }
7672             case NodeTypeFnCallExpr:
7673             case NodeTypeStructValueField:
7674                 force_generic = true;
7675                 break;
7676             default:
7677                 break;
7678         }
7679     }
7680 
7681     if (!force_generic) {
7682         if (exec != nullptr && exec->name != nullptr) {
7683             ZigType *import = get_scope_import(scope);
7684             Buf *namespace_name = buf_alloc();
7685             append_namespace_qualification(codegen, namespace_name, import);
7686             buf_append_buf(namespace_name, exec->name);
7687             buf_init_from_buf(out_bare_name, exec->name);
7688             return namespace_name;
7689         }
7690         if (exec != nullptr && exec->name_fn != nullptr) {
7691             Buf *name = buf_alloc();
7692             buf_append_buf(name, &exec->name_fn->symbol_name);
7693             buf_appendf(name, "(");
7694             render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope);
7695             buf_appendf(name, ")");
7696             buf_init_from_buf(out_bare_name, name);
7697             return name;
7698         }
7699     }
7700 
7701     ZigType *import = get_scope_import(scope);
7702     Buf *namespace_name = buf_alloc();
7703     append_namespace_qualification(codegen, namespace_name, import);
7704     RootStruct *root_struct = source_node->owner->data.structure.root_struct;
7705     TokenLoc tok_loc = root_struct->token_locs[source_node->main_token];
7706     buf_appendf(namespace_name, "%s:%u:%u", kind_name,
7707             tok_loc.line + 1, tok_loc.column + 1);
7708     buf_init_from_buf(out_bare_name, namespace_name);
7709     return namespace_name;
7710 }
7711 
astgen_container_decl(Stage1AstGen * ag,Scope * parent_scope,AstNode * node,ResultLoc * result_loc)7712 static Stage1ZirInst *astgen_container_decl(Stage1AstGen *ag, Scope *parent_scope,
7713         AstNode *node, ResultLoc *result_loc)
7714 {
7715     assert(node->type == NodeTypeContainerDecl);
7716 
7717     ContainerKind kind = node->data.container_decl.kind;
7718     Buf *bare_name = buf_alloc();
7719     Buf *name = get_anon_type_name(ag->codegen,
7720         ag->exec, container_string(kind), parent_scope, node, bare_name, result_loc);
7721 
7722     ContainerLayout layout = node->data.container_decl.layout;
7723     ZigType *container_type = get_partial_container_type(ag->codegen, parent_scope,
7724             kind, node, buf_ptr(name), bare_name, layout);
7725     ScopeDecls *child_scope = get_container_scope(container_type);
7726 
7727     for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) {
7728         AstNode *child_node = node->data.container_decl.decls.at(i);
7729         scan_decls(ag->codegen, child_scope, child_node);
7730     }
7731 
7732     TldContainer *tld_container = heap::c_allocator.create<TldContainer>();
7733     init_tld(&tld_container->base, TldIdContainer, bare_name, VisibModPub, node, parent_scope);
7734     tld_container->type_entry = container_type;
7735     tld_container->decls_scope = child_scope;
7736     ag->codegen->resolve_queue.append(&tld_container->base);
7737 
7738     // Add this to the list to mark as invalid if analyzing this exec fails.
7739     ag->exec->tld_list.append(&tld_container->base);
7740 
7741     return ir_build_const_type(ag, parent_scope, node, container_type);
7742 }
7743 
astgen_err_set_decl(Stage1AstGen * ag,Scope * parent_scope,AstNode * node)7744 static Stage1ZirInst *astgen_err_set_decl(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
7745     assert(node->type == NodeTypeErrorSetDecl);
7746 
7747     uint32_t err_count = node->data.err_set_decl.decls.length;
7748 
7749     Buf bare_name = BUF_INIT;
7750     Buf *type_name = get_anon_type_name(ag->codegen, ag->exec, "error", parent_scope, node, &bare_name, nullptr);
7751     ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
7752     buf_init_from_buf(&err_set_type->name, type_name);
7753     err_set_type->data.error_set.err_count = err_count;
7754     err_set_type->size_in_bits = ag->codegen->builtin_types.entry_global_error_set->size_in_bits;
7755     err_set_type->abi_align = ag->codegen->builtin_types.entry_global_error_set->abi_align;
7756     err_set_type->abi_size = ag->codegen->builtin_types.entry_global_error_set->abi_size;
7757     err_set_type->data.error_set.errors = heap::c_allocator.allocate<ErrorTableEntry *>(err_count);
7758 
7759     size_t errors_count = ag->codegen->errors_by_index.length + err_count;
7760     ErrorTableEntry **errors = heap::c_allocator.allocate<ErrorTableEntry *>(errors_count);
7761 
7762     for (uint32_t i = 0; i < err_count; i += 1) {
7763         AstNode *field_node = node->data.err_set_decl.decls.at(i);
7764         AstNode *symbol_node = ast_field_to_symbol_node(field_node);
7765         Buf *err_name = node_identifier_buf(symbol_node);
7766         ErrorTableEntry *err = heap::c_allocator.create<ErrorTableEntry>();
7767         err->decl_node = field_node;
7768         buf_init_from_buf(&err->name, err_name);
7769 
7770         auto existing_entry = ag->codegen->error_table.put_unique(err_name, err);
7771         if (existing_entry) {
7772             err->value = existing_entry->value->value;
7773         } else {
7774             size_t error_value_count = ag->codegen->errors_by_index.length;
7775             assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ag->codegen->err_tag_type->data.integral.bit_count));
7776             err->value = error_value_count;
7777             ag->codegen->errors_by_index.append(err);
7778         }
7779         err_set_type->data.error_set.errors[i] = err;
7780 
7781         ErrorTableEntry *prev_err = errors[err->value];
7782         if (prev_err != nullptr) {
7783             ErrorMsg *msg = add_node_error(ag->codegen, ast_field_to_symbol_node(err->decl_node),
7784                     buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name)));
7785             add_error_note(ag->codegen, msg, ast_field_to_symbol_node(prev_err->decl_node),
7786                     buf_sprintf("other error here"));
7787             return ag->codegen->invalid_inst_src;
7788         }
7789         errors[err->value] = err;
7790     }
7791     heap::c_allocator.deallocate(errors, errors_count);
7792     return ir_build_const_type(ag, parent_scope, node, err_set_type);
7793 }
7794 
astgen_fn_proto(Stage1AstGen * ag,Scope * parent_scope,AstNode * node)7795 static Stage1ZirInst *astgen_fn_proto(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
7796     assert(node->type == NodeTypeFnProto);
7797 
7798     size_t param_count = node->data.fn_proto.params.length;
7799     Stage1ZirInst **param_types = heap::c_allocator.allocate<Stage1ZirInst*>(param_count);
7800 
7801     bool is_var_args = false;
7802     for (size_t i = 0; i < param_count; i += 1) {
7803         AstNode *param_node = node->data.fn_proto.params.at(i);
7804         if (param_node->data.param_decl.is_var_args) {
7805             is_var_args = true;
7806             break;
7807         }
7808         if (param_node->data.param_decl.anytype_token == 0) {
7809             AstNode *type_node = param_node->data.param_decl.type;
7810             Stage1ZirInst *type_value = astgen_node(ag, type_node, parent_scope);
7811             if (type_value == ag->codegen->invalid_inst_src)
7812                 return ag->codegen->invalid_inst_src;
7813             param_types[i] = type_value;
7814         } else {
7815             param_types[i] = nullptr;
7816         }
7817     }
7818 
7819     Stage1ZirInst *align_value = nullptr;
7820     if (node->data.fn_proto.align_expr != nullptr) {
7821         align_value = astgen_node(ag, node->data.fn_proto.align_expr, parent_scope);
7822         if (align_value == ag->codegen->invalid_inst_src)
7823             return ag->codegen->invalid_inst_src;
7824     }
7825 
7826     Stage1ZirInst *callconv_value = nullptr;
7827     if (node->data.fn_proto.callconv_expr != nullptr) {
7828         callconv_value = astgen_node(ag, node->data.fn_proto.callconv_expr, parent_scope);
7829         if (callconv_value == ag->codegen->invalid_inst_src)
7830             return ag->codegen->invalid_inst_src;
7831     }
7832 
7833     Stage1ZirInst *return_type;
7834     if (node->data.fn_proto.return_type == nullptr) {
7835         return_type = ir_build_const_type(ag, parent_scope, node, ag->codegen->builtin_types.entry_void);
7836     } else {
7837         return_type = astgen_node(ag, node->data.fn_proto.return_type, parent_scope);
7838         if (return_type == ag->codegen->invalid_inst_src)
7839             return ag->codegen->invalid_inst_src;
7840     }
7841 
7842     return ir_build_fn_proto(ag, parent_scope, node, param_types, align_value, callconv_value, return_type, is_var_args);
7843 }
7844 
astgen_resume(Stage1AstGen * ag,Scope * scope,AstNode * node)7845 static Stage1ZirInst *astgen_resume(Stage1AstGen *ag, Scope *scope, AstNode *node) {
7846     assert(node->type == NodeTypeResume);
7847 
7848     Stage1ZirInst *target_inst = astgen_node_extra(ag, node->data.resume_expr.expr, scope, LValPtr, nullptr);
7849     if (target_inst == ag->codegen->invalid_inst_src)
7850         return ag->codegen->invalid_inst_src;
7851 
7852     return ir_build_resume_src(ag, scope, node, target_inst);
7853 }
7854 
astgen_await_expr(Stage1AstGen * ag,Scope * scope,AstNode * node,LVal lval,ResultLoc * result_loc)7855 static Stage1ZirInst *astgen_await_expr(Stage1AstGen *ag, Scope *scope, AstNode *node, LVal lval,
7856         ResultLoc *result_loc)
7857 {
7858     assert(node->type == NodeTypeAwaitExpr);
7859 
7860     bool is_nosuspend = get_scope_nosuspend(scope) != nullptr;
7861 
7862     AstNode *expr_node = node->data.await_expr.expr;
7863     if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) {
7864         AstNode *fn_ref_expr = expr_node->data.fn_call_expr.fn_ref_expr;
7865         Buf *name = node_identifier_buf(fn_ref_expr);
7866         auto entry = ag->codegen->builtin_fn_table.maybe_get(name);
7867         if (entry != nullptr) {
7868             BuiltinFnEntry *builtin_fn = entry->value;
7869             if (builtin_fn->id == BuiltinFnIdAsyncCall) {
7870                 return astgen_async_call(ag, scope, node, expr_node, lval, result_loc);
7871             }
7872         }
7873     }
7874 
7875     if (!ag->fn) {
7876         add_node_error(ag->codegen, node, buf_sprintf("await outside function definition"));
7877         return ag->codegen->invalid_inst_src;
7878     }
7879     ScopeSuspend *existing_suspend_scope = get_scope_suspend(scope);
7880     if (existing_suspend_scope) {
7881         if (!existing_suspend_scope->reported_err) {
7882             ErrorMsg *msg = add_node_error(ag->codegen, node, buf_sprintf("cannot await inside suspend block"));
7883             add_error_note(ag->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("suspend block here"));
7884             existing_suspend_scope->reported_err = true;
7885         }
7886         return ag->codegen->invalid_inst_src;
7887     }
7888 
7889     Stage1ZirInst *target_inst = astgen_node_extra(ag, expr_node, scope, LValPtr, nullptr);
7890     if (target_inst == ag->codegen->invalid_inst_src)
7891         return ag->codegen->invalid_inst_src;
7892 
7893     Stage1ZirInst *await_inst = ir_build_await_src(ag, scope, node, target_inst, result_loc, is_nosuspend);
7894     return ir_lval_wrap(ag, scope, await_inst, lval, result_loc);
7895 }
7896 
astgen_suspend(Stage1AstGen * ag,Scope * parent_scope,AstNode * node)7897 static Stage1ZirInst *astgen_suspend(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {
7898     assert(node->type == NodeTypeSuspend);
7899 
7900     if (!ag->fn) {
7901         add_node_error(ag->codegen, node, buf_sprintf("suspend outside function definition"));
7902         return ag->codegen->invalid_inst_src;
7903     }
7904     if (get_scope_nosuspend(parent_scope) != nullptr) {
7905         add_node_error(ag->codegen, node, buf_sprintf("suspend in nosuspend scope"));
7906         return ag->codegen->invalid_inst_src;
7907     }
7908 
7909     ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope);
7910     if (existing_suspend_scope) {
7911         if (!existing_suspend_scope->reported_err) {
7912             ErrorMsg *msg = add_node_error(ag->codegen, node, buf_sprintf("cannot suspend inside suspend block"));
7913             add_error_note(ag->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here"));
7914             existing_suspend_scope->reported_err = true;
7915         }
7916         return ag->codegen->invalid_inst_src;
7917     }
7918 
7919     Stage1ZirInstSuspendBegin *begin = ir_build_suspend_begin_src(ag, parent_scope, node);
7920     ScopeSuspend *suspend_scope = create_suspend_scope(ag->codegen, node, parent_scope);
7921     Scope *child_scope = &suspend_scope->base;
7922     Stage1ZirInst *susp_res = astgen_node(ag, node->data.suspend.block, child_scope);
7923     if (susp_res == ag->codegen->invalid_inst_src)
7924         return ag->codegen->invalid_inst_src;
7925     ir_build_check_statement_is_void(ag, child_scope, node->data.suspend.block, susp_res);
7926 
7927     return ir_build_suspend_finish_src(ag, parent_scope, node, begin);
7928 }
7929 
astgen_node_raw(Stage1AstGen * ag,AstNode * node,Scope * scope,LVal lval,ResultLoc * result_loc)7930 static Stage1ZirInst *astgen_node_raw(Stage1AstGen *ag, AstNode *node, Scope *scope,
7931         LVal lval, ResultLoc *result_loc)
7932 {
7933     assert(scope);
7934     switch (node->type) {
7935         case NodeTypeStructValueField:
7936         case NodeTypeParamDecl:
7937         case NodeTypeUsingNamespace:
7938         case NodeTypeSwitchProng:
7939         case NodeTypeSwitchRange:
7940         case NodeTypeStructField:
7941         case NodeTypeErrorSetField:
7942         case NodeTypeFnDef:
7943         case NodeTypeTestDecl:
7944             zig_unreachable();
7945         case NodeTypeBlock:
7946             return astgen_block(ag, scope, node, lval, result_loc);
7947         case NodeTypeGroupedExpr:
7948             return astgen_node_raw(ag, node->data.grouped_expr, scope, lval, result_loc);
7949         case NodeTypeBinOpExpr:
7950             return astgen_bin_op(ag, scope, node, lval, result_loc);
7951         case NodeTypeIntLiteral:
7952             return ir_lval_wrap(ag, scope, astgen_int_lit(ag, scope, node), lval, result_loc);
7953         case NodeTypeFloatLiteral:
7954             return ir_lval_wrap(ag, scope, astgen_float_lit(ag, scope, node), lval, result_loc);
7955         case NodeTypeCharLiteral:
7956             return ir_lval_wrap(ag, scope, astgen_char_lit(ag, scope, node), lval, result_loc);
7957         case NodeTypeIdentifier:
7958             return astgen_identifier(ag, scope, node, lval, result_loc);
7959         case NodeTypeFnCallExpr:
7960             return astgen_fn_call(ag, scope, node, lval, result_loc);
7961         case NodeTypeIfBoolExpr:
7962             return astgen_if_bool_expr(ag, scope, node, lval, result_loc);
7963         case NodeTypePrefixOpExpr:
7964             return astgen_prefix_op_expr(ag, scope, node, lval, result_loc);
7965         case NodeTypeContainerInitExpr:
7966             return astgen_container_init_expr(ag, scope, node, lval, result_loc);
7967         case NodeTypeVariableDeclaration:
7968             return astgen_var_decl(ag, scope, node);
7969         case NodeTypeWhileExpr:
7970             return astgen_while_expr(ag, scope, node, lval, result_loc);
7971         case NodeTypeForExpr:
7972             return astgen_for_expr(ag, scope, node, lval, result_loc);
7973         case NodeTypeArrayAccessExpr:
7974             return astgen_array_access(ag, scope, node, lval, result_loc);
7975         case NodeTypeReturnExpr:
7976             return astgen_return(ag, scope, node, lval, result_loc);
7977         case NodeTypeFieldAccessExpr:
7978             {
7979                 Stage1ZirInst *ptr_instruction = astgen_field_access(ag, scope, node);
7980                 if (ptr_instruction == ag->codegen->invalid_inst_src)
7981                     return ptr_instruction;
7982                 if (lval == LValPtr || lval == LValAssign)
7983                     return ptr_instruction;
7984 
7985                 Stage1ZirInst *load_ptr = ir_build_load_ptr(ag, scope, node, ptr_instruction);
7986                 return ir_expr_wrap(ag, scope, load_ptr, result_loc);
7987             }
7988         case NodeTypePtrDeref: {
7989             AstNode *expr_node = node->data.ptr_deref_expr.target;
7990 
7991             LVal child_lval = lval;
7992             if (child_lval == LValAssign)
7993                 child_lval = LValPtr;
7994 
7995             Stage1ZirInst *value = astgen_node_extra(ag, expr_node, scope, child_lval, nullptr);
7996             if (value == ag->codegen->invalid_inst_src)
7997                 return value;
7998 
7999             // We essentially just converted any lvalue from &(x.*) to (&x).*;
8000             // this inhibits checking that x is a pointer later, so we directly
8001             // record whether the pointer check is needed
8002             Stage1ZirInst *un_op = ir_build_un_op_lval(ag, scope, node, IrUnOpDereference, value, lval, result_loc);
8003             return ir_expr_wrap(ag, scope, un_op, result_loc);
8004         }
8005         case NodeTypeUnwrapOptional: {
8006             AstNode *expr_node = node->data.unwrap_optional.expr;
8007 
8008             Stage1ZirInst *maybe_ptr = astgen_node_extra(ag, expr_node, scope, LValPtr, nullptr);
8009             if (maybe_ptr == ag->codegen->invalid_inst_src)
8010                 return ag->codegen->invalid_inst_src;
8011 
8012             Stage1ZirInst *unwrapped_ptr = ir_build_optional_unwrap_ptr(ag, scope, node, maybe_ptr, true );
8013             if (lval == LValPtr || lval == LValAssign)
8014                 return unwrapped_ptr;
8015 
8016             Stage1ZirInst *load_ptr = ir_build_load_ptr(ag, scope, node, unwrapped_ptr);
8017             return ir_expr_wrap(ag, scope, load_ptr, result_loc);
8018         }
8019         case NodeTypeBoolLiteral:
8020             return ir_lval_wrap(ag, scope, astgen_bool_literal(ag, scope, node), lval, result_loc);
8021         case NodeTypeArrayType:
8022             return ir_lval_wrap(ag, scope, astgen_array_type(ag, scope, node), lval, result_loc);
8023         case NodeTypePointerType:
8024             return ir_lval_wrap(ag, scope, astgen_pointer_type(ag, scope, node), lval, result_loc);
8025         case NodeTypeAnyFrameType:
8026             return ir_lval_wrap(ag, scope, astgen_anyframe_type(ag, scope, node), lval, result_loc);
8027         case NodeTypeStringLiteral:
8028             return ir_lval_wrap(ag, scope, astgen_string_literal(ag, scope, node), lval, result_loc);
8029         case NodeTypeUndefinedLiteral:
8030             return ir_lval_wrap(ag, scope, astgen_undefined_literal(ag, scope, node), lval, result_loc);
8031         case NodeTypeAsmExpr:
8032             return ir_lval_wrap(ag, scope, astgen_asm_expr(ag, scope, node), lval, result_loc);
8033         case NodeTypeNullLiteral:
8034             return ir_lval_wrap(ag, scope, astgen_null_literal(ag, scope, node), lval, result_loc);
8035         case NodeTypeIfErrorExpr:
8036             return astgen_if_err_expr(ag, scope, node, lval, result_loc);
8037         case NodeTypeIfOptional:
8038             return astgen_if_optional_expr(ag, scope, node, lval, result_loc);
8039         case NodeTypeSwitchExpr:
8040             return astgen_switch_expr(ag, scope, node, lval, result_loc);
8041         case NodeTypeCompTime:
8042             return ir_expr_wrap(ag, scope, astgen_comptime(ag, scope, node, lval), result_loc);
8043         case NodeTypeNoSuspend:
8044             return ir_expr_wrap(ag, scope, astgen_nosuspend(ag, scope, node, lval), result_loc);
8045         case NodeTypeErrorType:
8046             return ir_lval_wrap(ag, scope, astgen_error_type(ag, scope, node), lval, result_loc);
8047         case NodeTypeBreak:
8048             return ir_lval_wrap(ag, scope, astgen_break(ag, scope, node), lval, result_loc);
8049         case NodeTypeContinue:
8050             return ir_lval_wrap(ag, scope, astgen_continue(ag, scope, node), lval, result_loc);
8051         case NodeTypeUnreachable:
8052             return ir_build_unreachable(ag, scope, node);
8053         case NodeTypeDefer:
8054             return ir_lval_wrap(ag, scope, astgen_defer(ag, scope, node), lval, result_loc);
8055         case NodeTypeSliceExpr:
8056             return astgen_slice(ag, scope, node, lval, result_loc);
8057         case NodeTypeCatchExpr:
8058             return astgen_catch(ag, scope, node, lval, result_loc);
8059         case NodeTypeContainerDecl:
8060             return ir_lval_wrap(ag, scope, astgen_container_decl(ag, scope, node, result_loc), lval, result_loc);
8061         case NodeTypeFnProto:
8062             return ir_lval_wrap(ag, scope, astgen_fn_proto(ag, scope, node), lval, result_loc);
8063         case NodeTypeErrorSetDecl:
8064             return ir_lval_wrap(ag, scope, astgen_err_set_decl(ag, scope, node), lval, result_loc);
8065         case NodeTypeResume:
8066             return ir_lval_wrap(ag, scope, astgen_resume(ag, scope, node), lval, result_loc);
8067         case NodeTypeAwaitExpr:
8068             return astgen_await_expr(ag, scope, node, lval, result_loc);
8069         case NodeTypeSuspend:
8070             return ir_lval_wrap(ag, scope, astgen_suspend(ag, scope, node), lval, result_loc);
8071         case NodeTypeEnumLiteral:
8072             return ir_lval_wrap(ag, scope, astgen_enum_literal(ag, scope, node), lval, result_loc);
8073         case NodeTypeInferredArrayType:
8074             add_node_error(ag->codegen, node,
8075                 buf_sprintf("inferred array size invalid here"));
8076             return ag->codegen->invalid_inst_src;
8077         case NodeTypeAnyTypeField:
8078             return ir_lval_wrap(ag, scope,
8079                     ir_build_const_type(ag, scope, node, ag->codegen->builtin_types.entry_anytype), lval, result_loc);
8080     }
8081     zig_unreachable();
8082 }
8083 
no_result_loc(void)8084 ResultLoc *no_result_loc(void) {
8085     ResultLocNone *result_loc_none = heap::c_allocator.create<ResultLocNone>();
8086     result_loc_none->base.id = ResultLocIdNone;
8087     return &result_loc_none->base;
8088 }
8089 
astgen_node_extra(Stage1AstGen * ag,AstNode * node,Scope * scope,LVal lval,ResultLoc * result_loc)8090 static Stage1ZirInst *astgen_node_extra(Stage1AstGen *ag, AstNode *node, Scope *scope, LVal lval,
8091         ResultLoc *result_loc)
8092 {
8093     if (lval == LValAssign) {
8094         switch (node->type) {
8095             case NodeTypeStructValueField:
8096             case NodeTypeParamDecl:
8097             case NodeTypeUsingNamespace:
8098             case NodeTypeSwitchProng:
8099             case NodeTypeSwitchRange:
8100             case NodeTypeStructField:
8101             case NodeTypeErrorSetField:
8102             case NodeTypeFnDef:
8103             case NodeTypeTestDecl:
8104                 zig_unreachable();
8105 
8106             // cannot be assigned to
8107             case NodeTypeBlock:
8108             case NodeTypeGroupedExpr:
8109             case NodeTypeBinOpExpr:
8110             case NodeTypeIntLiteral:
8111             case NodeTypeFloatLiteral:
8112             case NodeTypeCharLiteral:
8113             case NodeTypeIfBoolExpr:
8114             case NodeTypeContainerInitExpr:
8115             case NodeTypeVariableDeclaration:
8116             case NodeTypeWhileExpr:
8117             case NodeTypeForExpr:
8118             case NodeTypeReturnExpr:
8119             case NodeTypeBoolLiteral:
8120             case NodeTypeArrayType:
8121             case NodeTypePointerType:
8122             case NodeTypeAnyFrameType:
8123             case NodeTypeStringLiteral:
8124             case NodeTypeUndefinedLiteral:
8125             case NodeTypeAsmExpr:
8126             case NodeTypeNullLiteral:
8127             case NodeTypeIfErrorExpr:
8128             case NodeTypeIfOptional:
8129             case NodeTypeSwitchExpr:
8130             case NodeTypeCompTime:
8131             case NodeTypeNoSuspend:
8132             case NodeTypeErrorType:
8133             case NodeTypeBreak:
8134             case NodeTypeContinue:
8135             case NodeTypeUnreachable:
8136             case NodeTypeDefer:
8137             case NodeTypeSliceExpr:
8138             case NodeTypeCatchExpr:
8139             case NodeTypeContainerDecl:
8140             case NodeTypeFnProto:
8141             case NodeTypeErrorSetDecl:
8142             case NodeTypeResume:
8143             case NodeTypeAwaitExpr:
8144             case NodeTypeSuspend:
8145             case NodeTypeEnumLiteral:
8146             case NodeTypeInferredArrayType:
8147             case NodeTypeAnyTypeField:
8148             case NodeTypePrefixOpExpr:
8149                 add_node_error(ag->codegen, node,
8150                     buf_sprintf("invalid left-hand side to assignment"));
8151                 return ag->codegen->invalid_inst_src;
8152 
8153             // @field can be assigned to
8154             case NodeTypeFnCallExpr:
8155                 if (node->data.fn_call_expr.modifier == CallModifierBuiltin) {
8156                     AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr;
8157                     Buf *name = node_identifier_buf(fn_ref_expr);
8158                     auto entry = ag->codegen->builtin_fn_table.maybe_get(name);
8159 
8160                     if (!entry) {
8161                         add_node_error(ag->codegen, node,
8162                                 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name)));
8163                         return ag->codegen->invalid_inst_src;
8164                     }
8165 
8166                     if (entry->value->id == BuiltinFnIdField) {
8167                         break;
8168                     }
8169                 }
8170                 add_node_error(ag->codegen, node,
8171                     buf_sprintf("invalid left-hand side to assignment"));
8172                 return ag->codegen->invalid_inst_src;
8173 
8174 
8175             // can be assigned to
8176             case NodeTypeUnwrapOptional:
8177             case NodeTypePtrDeref:
8178             case NodeTypeFieldAccessExpr:
8179             case NodeTypeArrayAccessExpr:
8180             case NodeTypeIdentifier:
8181                 break;
8182         }
8183     }
8184     if (result_loc == nullptr) {
8185         // Create a result location indicating there is none - but if one gets created
8186         // it will be properly distributed.
8187         result_loc = no_result_loc();
8188         ir_build_reset_result(ag, scope, node, result_loc);
8189     }
8190     Scope *child_scope;
8191     if (ag->exec->is_inline ||
8192         (ag->fn != nullptr && ag->fn->child_scope == scope))
8193     {
8194         child_scope = scope;
8195     } else {
8196         child_scope = &create_expr_scope(ag->codegen, node, scope)->base;
8197     }
8198     Stage1ZirInst *result = astgen_node_raw(ag, node, child_scope, lval, result_loc);
8199     if (result == ag->codegen->invalid_inst_src) {
8200         if (ag->exec->first_err_trace_msg == nullptr) {
8201             ag->exec->first_err_trace_msg = ag->codegen->trace_err;
8202         }
8203     }
8204     return result;
8205 }
8206 
astgen_node(Stage1AstGen * ag,AstNode * node,Scope * scope)8207 static Stage1ZirInst *astgen_node(Stage1AstGen *ag, AstNode *node, Scope *scope) {
8208     return astgen_node_extra(ag, node, scope, LValNone, nullptr);
8209 }
8210 
stage1_astgen(CodeGen * codegen,AstNode * node,Scope * scope,Stage1Zir * stage1_zir,ZigFn * fn,bool in_c_import_scope)8211 bool stage1_astgen(CodeGen *codegen, AstNode *node, Scope *scope, Stage1Zir *stage1_zir,
8212         ZigFn *fn, bool in_c_import_scope)
8213 {
8214     assert(node->owner);
8215 
8216     Stage1AstGen ir_builder = {0};
8217     Stage1AstGen *ag = &ir_builder;
8218 
8219     ag->codegen = codegen;
8220     ag->fn = fn;
8221     ag->in_c_import_scope = in_c_import_scope;
8222     ag->exec = stage1_zir;
8223     ag->main_block_node = node;
8224 
8225     Stage1ZirBasicBlock *entry_block = ir_create_basic_block(ag, scope, "Entry");
8226     ir_set_cursor_at_end_and_append_block(ag, entry_block);
8227     // Entry block gets a reference because we enter it to begin.
8228     ir_ref_bb(ag->current_basic_block);
8229 
8230     Stage1ZirInst *result = astgen_node_extra(ag, node, scope, LValNone, nullptr);
8231 
8232     if (result == ag->codegen->invalid_inst_src)
8233         return false;
8234 
8235     if (ag->exec->first_err_trace_msg != nullptr) {
8236         codegen->trace_err = ag->exec->first_err_trace_msg;
8237         return false;
8238     }
8239 
8240     if (!instr_is_unreachable(result)) {
8241         ir_build_add_implicit_return_type(ag, scope, result->source_node, result, nullptr);
8242         // no need for save_err_ret_addr because this cannot return error
8243         ResultLocReturn *result_loc_ret = heap::c_allocator.create<ResultLocReturn>();
8244         result_loc_ret->base.id = ResultLocIdReturn;
8245         ir_build_reset_result(ag, scope, node, &result_loc_ret->base);
8246         ir_build_end_expr(ag, scope, node, result, &result_loc_ret->base);
8247         ir_build_return_src(ag, scope, result->source_node, result);
8248     }
8249 
8250     return true;
8251 }
8252 
stage1_astgen_fn(CodeGen * codegen,ZigFn * fn)8253 bool stage1_astgen_fn(CodeGen *codegen, ZigFn *fn) {
8254     assert(fn != nullptr);
8255     assert(fn->child_scope != nullptr);
8256     return stage1_astgen(codegen, fn->body_node, fn->child_scope, fn->stage1_zir, fn, false);
8257 }
8258 
invalidate_exec(Stage1Zir * exec,ErrorMsg * msg)8259 void invalidate_exec(Stage1Zir *exec, ErrorMsg *msg) {
8260     if (exec->first_err_trace_msg != nullptr)
8261         return;
8262 
8263     exec->first_err_trace_msg = msg;
8264 
8265     for (size_t i = 0; i < exec->tld_list.length; i += 1) {
8266         exec->tld_list.items[i]->resolution = TldResolutionInvalid;
8267     }
8268 }
8269 
ast_field_to_symbol_node(AstNode * err_set_field_node)8270 AstNode *ast_field_to_symbol_node(AstNode *err_set_field_node) {
8271     if (err_set_field_node->type == NodeTypeIdentifier) {
8272         return err_set_field_node;
8273     } else if (err_set_field_node->type == NodeTypeErrorSetField) {
8274         assert(err_set_field_node->data.err_set_field.field_name->type == NodeTypeIdentifier);
8275         return err_set_field_node->data.err_set_field.field_name;
8276     } else {
8277         return err_set_field_node;
8278     }
8279 }
8280 
ir_add_call_stack_errors_gen(CodeGen * codegen,Stage1Air * exec,ErrorMsg * err_msg,int limit)8281 void ir_add_call_stack_errors_gen(CodeGen *codegen, Stage1Air *exec, ErrorMsg *err_msg, int limit) {
8282     if (!exec || !exec->source_node || limit < 0) return;
8283     add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here"));
8284 
8285     ir_add_call_stack_errors_gen(codegen, exec->parent_exec, err_msg, limit - 1);
8286 }
8287 
src()8288 void Stage1ZirInst::src() {
8289     Stage1ZirInst *inst = this;
8290     if (inst->source_node != nullptr) {
8291         inst->source_node->src();
8292     } else {
8293         fprintf(stderr, "(null source node)\n");
8294     }
8295 }
8296 
8297