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