blob 360ff00b (977098B) - Raw
1 /* 2 * Copyright (c) 2016 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 "analyze.hpp" 9 #include "ast_render.hpp" 10 #include "error.hpp" 11 #include "ir.hpp" 12 #include "ir_print.hpp" 13 #include "os.hpp" 14 #include "range_set.hpp" 15 #include "softfloat.hpp" 16 #include "translate_c.hpp" 17 #include "util.hpp" 18 19 struct IrExecContext { 20 ZigList<ConstExprValue *> mem_slot_list; 21 }; 22 23 struct IrBuilder { 24 CodeGen *codegen; 25 IrExecutable *exec; 26 IrBasicBlock *current_basic_block; 27 }; 28 29 struct IrAnalyze { 30 CodeGen *codegen; 31 IrBuilder old_irb; 32 IrBuilder new_irb; 33 IrExecContext exec_context; 34 size_t old_bb_index; 35 size_t instruction_index; 36 ZigType *explicit_return_type; 37 ZigList<IrInstruction *> src_implicit_return_type_list; 38 IrBasicBlock *const_predecessor_bb; 39 }; 40 41 enum ConstCastResultId { 42 ConstCastResultIdOk, 43 ConstCastResultIdInvalid, 44 ConstCastResultIdErrSet, 45 ConstCastResultIdErrSetGlobal, 46 ConstCastResultIdPointerChild, 47 ConstCastResultIdSliceChild, 48 ConstCastResultIdOptionalChild, 49 ConstCastResultIdErrorUnionPayload, 50 ConstCastResultIdErrorUnionErrorSet, 51 ConstCastResultIdFnAlign, 52 ConstCastResultIdFnCC, 53 ConstCastResultIdFnVarArgs, 54 ConstCastResultIdFnIsGeneric, 55 ConstCastResultIdFnReturnType, 56 ConstCastResultIdFnArgCount, 57 ConstCastResultIdFnGenericArgCount, 58 ConstCastResultIdFnArg, 59 ConstCastResultIdFnArgNoAlias, 60 ConstCastResultIdType, 61 ConstCastResultIdUnresolvedInferredErrSet, 62 ConstCastResultIdAsyncAllocatorType, 63 ConstCastResultIdNullWrapPtr 64 }; 65 66 struct ConstCastOnly; 67 struct ConstCastArg { 68 size_t arg_index; 69 ConstCastOnly *child; 70 }; 71 72 struct ConstCastArgNoAlias { 73 size_t arg_index; 74 }; 75 76 struct ConstCastOptionalMismatch; 77 struct ConstCastPointerMismatch; 78 struct ConstCastSliceMismatch; 79 struct ConstCastErrUnionErrSetMismatch; 80 struct ConstCastErrUnionPayloadMismatch; 81 struct ConstCastErrSetMismatch; 82 struct ConstCastTypeMismatch; 83 84 struct ConstCastOnly { 85 ConstCastResultId id; 86 union { 87 ConstCastErrSetMismatch *error_set_mismatch; 88 ConstCastPointerMismatch *pointer_mismatch; 89 ConstCastSliceMismatch *slice_mismatch; 90 ConstCastOptionalMismatch *optional; 91 ConstCastErrUnionPayloadMismatch *error_union_payload; 92 ConstCastErrUnionErrSetMismatch *error_union_error_set; 93 ConstCastTypeMismatch *type_mismatch; 94 ConstCastOnly *return_type; 95 ConstCastOnly *async_allocator_type; 96 ConstCastOnly *null_wrap_ptr_child; 97 ConstCastArg fn_arg; 98 ConstCastArgNoAlias arg_no_alias; 99 } data; 100 }; 101 102 struct ConstCastTypeMismatch { 103 ZigType *wanted_type; 104 ZigType *actual_type; 105 }; 106 107 struct ConstCastOptionalMismatch { 108 ConstCastOnly child; 109 ZigType *wanted_child; 110 ZigType *actual_child; 111 }; 112 113 struct ConstCastPointerMismatch { 114 ConstCastOnly child; 115 ZigType *wanted_child; 116 ZigType *actual_child; 117 }; 118 119 struct ConstCastSliceMismatch { 120 ConstCastOnly child; 121 ZigType *wanted_child; 122 ZigType *actual_child; 123 }; 124 125 struct ConstCastErrUnionErrSetMismatch { 126 ConstCastOnly child; 127 ZigType *wanted_err_set; 128 ZigType *actual_err_set; 129 }; 130 131 struct ConstCastErrUnionPayloadMismatch { 132 ConstCastOnly child; 133 ZigType *wanted_payload; 134 ZigType *actual_payload; 135 }; 136 137 struct ConstCastErrSetMismatch { 138 ZigList<ErrorTableEntry *> missing_errors; 139 }; 140 141 static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope); 142 static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval); 143 static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); 144 static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type); 145 static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr); 146 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg); 147 static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 148 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type); 149 static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, ZigVar *var); 150 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op); 151 static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval); 152 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align); 153 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align); 154 static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); 155 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val); 156 static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, 157 ConstExprValue *out_val, ConstExprValue *ptr_val); 158 static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, 159 ZigType *dest_type, IrInstruction *dest_type_src); 160 161 static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { 162 assert(get_src_ptr_type(const_val->type) != nullptr); 163 assert(const_val->special == ConstValSpecialStatic); 164 ConstExprValue *result; 165 switch (const_val->data.x_ptr.special) { 166 case ConstPtrSpecialInvalid: 167 zig_unreachable(); 168 case ConstPtrSpecialRef: 169 result = const_val->data.x_ptr.data.ref.pointee; 170 break; 171 case ConstPtrSpecialBaseArray: 172 expand_undef_array(g, const_val->data.x_ptr.data.base_array.array_val); 173 result = &const_val->data.x_ptr.data.base_array.array_val->data.x_array.data.s_none.elements[ 174 const_val->data.x_ptr.data.base_array.elem_index]; 175 break; 176 case ConstPtrSpecialBaseStruct: 177 result = &const_val->data.x_ptr.data.base_struct.struct_val->data.x_struct.fields[ 178 const_val->data.x_ptr.data.base_struct.field_index]; 179 break; 180 case ConstPtrSpecialHardCodedAddr: 181 zig_unreachable(); 182 case ConstPtrSpecialDiscard: 183 zig_unreachable(); 184 case ConstPtrSpecialFunction: 185 zig_unreachable(); 186 } 187 assert(result != nullptr); 188 return result; 189 } 190 191 static bool types_have_same_zig_comptime_repr(ZigType *a, ZigType *b) { 192 if (a == b) 193 return true; 194 195 if (a->id == b->id) 196 return true; 197 198 if (get_codegen_ptr_type(a) != nullptr && get_codegen_ptr_type(b) != nullptr) 199 return true; 200 201 return false; 202 } 203 204 ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { 205 ConstExprValue *result = const_ptr_pointee_unchecked(g, const_val); 206 if (const_val->type->id == ZigTypeIdPointer) { 207 assert(types_have_same_zig_comptime_repr(const_val->type->data.pointer.child_type, result->type)); 208 } 209 return result; 210 } 211 212 static bool ir_should_inline(IrExecutable *exec, Scope *scope) { 213 if (exec->is_inline) 214 return true; 215 216 while (scope != nullptr) { 217 if (scope->id == ScopeIdCompTime) 218 return true; 219 if (scope->id == ScopeIdFnDef) 220 break; 221 scope = scope->parent; 222 } 223 return false; 224 } 225 226 static void ir_instruction_append(IrBasicBlock *basic_block, IrInstruction *instruction) { 227 assert(basic_block); 228 assert(instruction); 229 basic_block->instruction_list.append(instruction); 230 } 231 232 static size_t exec_next_debug_id(IrExecutable *exec) { 233 size_t result = exec->next_debug_id; 234 exec->next_debug_id += 1; 235 return result; 236 } 237 238 static size_t exec_next_mem_slot(IrExecutable *exec) { 239 size_t result = exec->mem_slot_count; 240 exec->mem_slot_count += 1; 241 return result; 242 } 243 244 static ZigFn *exec_fn_entry(IrExecutable *exec) { 245 return exec->fn_entry; 246 } 247 248 static Buf *exec_c_import_buf(IrExecutable *exec) { 249 return exec->c_import_buf; 250 } 251 252 static bool value_is_comptime(ConstExprValue *const_val) { 253 return const_val->special != ConstValSpecialRuntime; 254 } 255 256 static bool instr_is_comptime(IrInstruction *instruction) { 257 return value_is_comptime(&instruction->value); 258 } 259 260 static bool instr_is_unreachable(IrInstruction *instruction) { 261 return instruction->value.type && instruction->value.type->id == ZigTypeIdUnreachable; 262 } 263 264 static void ir_link_new_bb(IrBasicBlock *new_bb, IrBasicBlock *old_bb) { 265 new_bb->other = old_bb; 266 old_bb->other = new_bb; 267 } 268 269 static void ir_ref_bb(IrBasicBlock *bb) { 270 bb->ref_count += 1; 271 } 272 273 static void ir_ref_instruction(IrInstruction *instruction, IrBasicBlock *cur_bb) { 274 assert(instruction->id != IrInstructionIdInvalid); 275 instruction->ref_count += 1; 276 if (instruction->owner_bb != cur_bb && !instr_is_comptime(instruction)) 277 ir_ref_bb(instruction->owner_bb); 278 } 279 280 static void ir_ref_var(ZigVar *var) { 281 var->ref_count += 1; 282 } 283 284 static IrBasicBlock *ir_create_basic_block(IrBuilder *irb, Scope *scope, const char *name_hint) { 285 IrBasicBlock *result = allocate<IrBasicBlock>(1); 286 result->scope = scope; 287 result->name_hint = name_hint; 288 result->debug_id = exec_next_debug_id(irb->exec); 289 return result; 290 } 291 292 static IrBasicBlock *ir_build_bb_from(IrBuilder *irb, IrBasicBlock *other_bb) { 293 IrBasicBlock *new_bb = ir_create_basic_block(irb, other_bb->scope, other_bb->name_hint); 294 ir_link_new_bb(new_bb, other_bb); 295 return new_bb; 296 } 297 298 static constexpr IrInstructionId ir_instruction_id(IrInstructionCondBr *) { 299 return IrInstructionIdCondBr; 300 } 301 302 static constexpr IrInstructionId ir_instruction_id(IrInstructionBr *) { 303 return IrInstructionIdBr; 304 } 305 306 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchBr *) { 307 return IrInstructionIdSwitchBr; 308 } 309 310 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchVar *) { 311 return IrInstructionIdSwitchVar; 312 } 313 314 static constexpr IrInstructionId ir_instruction_id(IrInstructionSwitchTarget *) { 315 return IrInstructionIdSwitchTarget; 316 } 317 318 static constexpr IrInstructionId ir_instruction_id(IrInstructionPhi *) { 319 return IrInstructionIdPhi; 320 } 321 322 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnOp *) { 323 return IrInstructionIdUnOp; 324 } 325 326 static constexpr IrInstructionId ir_instruction_id(IrInstructionBinOp *) { 327 return IrInstructionIdBinOp; 328 } 329 330 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclVar *) { 331 return IrInstructionIdDeclVar; 332 } 333 334 static constexpr IrInstructionId ir_instruction_id(IrInstructionExport *) { 335 return IrInstructionIdExport; 336 } 337 338 static constexpr IrInstructionId ir_instruction_id(IrInstructionLoadPtr *) { 339 return IrInstructionIdLoadPtr; 340 } 341 342 static constexpr IrInstructionId ir_instruction_id(IrInstructionStorePtr *) { 343 return IrInstructionIdStorePtr; 344 } 345 346 static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldPtr *) { 347 return IrInstructionIdFieldPtr; 348 } 349 350 static constexpr IrInstructionId ir_instruction_id(IrInstructionStructFieldPtr *) { 351 return IrInstructionIdStructFieldPtr; 352 } 353 354 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionFieldPtr *) { 355 return IrInstructionIdUnionFieldPtr; 356 } 357 358 static constexpr IrInstructionId ir_instruction_id(IrInstructionElemPtr *) { 359 return IrInstructionIdElemPtr; 360 } 361 362 static constexpr IrInstructionId ir_instruction_id(IrInstructionVarPtr *) { 363 return IrInstructionIdVarPtr; 364 } 365 366 static constexpr IrInstructionId ir_instruction_id(IrInstructionCall *) { 367 return IrInstructionIdCall; 368 } 369 370 static constexpr IrInstructionId ir_instruction_id(IrInstructionConst *) { 371 return IrInstructionIdConst; 372 } 373 374 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturn *) { 375 return IrInstructionIdReturn; 376 } 377 378 static constexpr IrInstructionId ir_instruction_id(IrInstructionCast *) { 379 return IrInstructionIdCast; 380 } 381 382 static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitList *) { 383 return IrInstructionIdContainerInitList; 384 } 385 386 static constexpr IrInstructionId ir_instruction_id(IrInstructionContainerInitFields *) { 387 return IrInstructionIdContainerInitFields; 388 } 389 390 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnreachable *) { 391 return IrInstructionIdUnreachable; 392 } 393 394 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeOf *) { 395 return IrInstructionIdTypeOf; 396 } 397 398 static constexpr IrInstructionId ir_instruction_id(IrInstructionToPtrType *) { 399 return IrInstructionIdToPtrType; 400 } 401 402 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrTypeChild *) { 403 return IrInstructionIdPtrTypeChild; 404 } 405 406 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) { 407 return IrInstructionIdSetCold; 408 } 409 410 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetRuntimeSafety *) { 411 return IrInstructionIdSetRuntimeSafety; 412 } 413 414 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFloatMode *) { 415 return IrInstructionIdSetFloatMode; 416 } 417 418 static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayType *) { 419 return IrInstructionIdArrayType; 420 } 421 422 static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseType *) { 423 return IrInstructionIdPromiseType; 424 } 425 426 static constexpr IrInstructionId ir_instruction_id(IrInstructionSliceType *) { 427 return IrInstructionIdSliceType; 428 } 429 430 static constexpr IrInstructionId ir_instruction_id(IrInstructionAsm *) { 431 return IrInstructionIdAsm; 432 } 433 434 static constexpr IrInstructionId ir_instruction_id(IrInstructionSizeOf *) { 435 return IrInstructionIdSizeOf; 436 } 437 438 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestNonNull *) { 439 return IrInstructionIdTestNonNull; 440 } 441 442 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapOptional *) { 443 return IrInstructionIdUnwrapOptional; 444 } 445 446 static constexpr IrInstructionId ir_instruction_id(IrInstructionClz *) { 447 return IrInstructionIdClz; 448 } 449 450 static constexpr IrInstructionId ir_instruction_id(IrInstructionCtz *) { 451 return IrInstructionIdCtz; 452 } 453 454 static constexpr IrInstructionId ir_instruction_id(IrInstructionPopCount *) { 455 return IrInstructionIdPopCount; 456 } 457 458 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionTag *) { 459 return IrInstructionIdUnionTag; 460 } 461 462 static constexpr IrInstructionId ir_instruction_id(IrInstructionImport *) { 463 return IrInstructionIdImport; 464 } 465 466 static constexpr IrInstructionId ir_instruction_id(IrInstructionCImport *) { 467 return IrInstructionIdCImport; 468 } 469 470 static constexpr IrInstructionId ir_instruction_id(IrInstructionCInclude *) { 471 return IrInstructionIdCInclude; 472 } 473 474 static constexpr IrInstructionId ir_instruction_id(IrInstructionCDefine *) { 475 return IrInstructionIdCDefine; 476 } 477 478 static constexpr IrInstructionId ir_instruction_id(IrInstructionCUndef *) { 479 return IrInstructionIdCUndef; 480 } 481 482 static constexpr IrInstructionId ir_instruction_id(IrInstructionArrayLen *) { 483 return IrInstructionIdArrayLen; 484 } 485 486 static constexpr IrInstructionId ir_instruction_id(IrInstructionRef *) { 487 return IrInstructionIdRef; 488 } 489 490 static constexpr IrInstructionId ir_instruction_id(IrInstructionStructInit *) { 491 return IrInstructionIdStructInit; 492 } 493 494 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInit *) { 495 return IrInstructionIdUnionInit; 496 } 497 498 static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileErr *) { 499 return IrInstructionIdCompileErr; 500 } 501 502 static constexpr IrInstructionId ir_instruction_id(IrInstructionCompileLog *) { 503 return IrInstructionIdCompileLog; 504 } 505 506 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrName *) { 507 return IrInstructionIdErrName; 508 } 509 510 static constexpr IrInstructionId ir_instruction_id(IrInstructionEmbedFile *) { 511 return IrInstructionIdEmbedFile; 512 } 513 514 static constexpr IrInstructionId ir_instruction_id(IrInstructionCmpxchg *) { 515 return IrInstructionIdCmpxchg; 516 } 517 518 static constexpr IrInstructionId ir_instruction_id(IrInstructionFence *) { 519 return IrInstructionIdFence; 520 } 521 522 static constexpr IrInstructionId ir_instruction_id(IrInstructionTruncate *) { 523 return IrInstructionIdTruncate; 524 } 525 526 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntCast *) { 527 return IrInstructionIdIntCast; 528 } 529 530 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatCast *) { 531 return IrInstructionIdFloatCast; 532 } 533 534 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrSetCast *) { 535 return IrInstructionIdErrSetCast; 536 } 537 538 static constexpr IrInstructionId ir_instruction_id(IrInstructionToBytes *) { 539 return IrInstructionIdToBytes; 540 } 541 542 static constexpr IrInstructionId ir_instruction_id(IrInstructionFromBytes *) { 543 return IrInstructionIdFromBytes; 544 } 545 546 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToFloat *) { 547 return IrInstructionIdIntToFloat; 548 } 549 550 static constexpr IrInstructionId ir_instruction_id(IrInstructionFloatToInt *) { 551 return IrInstructionIdFloatToInt; 552 } 553 554 static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolToInt *) { 555 return IrInstructionIdBoolToInt; 556 } 557 558 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntType *) { 559 return IrInstructionIdIntType; 560 } 561 562 static constexpr IrInstructionId ir_instruction_id(IrInstructionBoolNot *) { 563 return IrInstructionIdBoolNot; 564 } 565 566 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemset *) { 567 return IrInstructionIdMemset; 568 } 569 570 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemcpy *) { 571 return IrInstructionIdMemcpy; 572 } 573 574 static constexpr IrInstructionId ir_instruction_id(IrInstructionSlice *) { 575 return IrInstructionIdSlice; 576 } 577 578 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberCount *) { 579 return IrInstructionIdMemberCount; 580 } 581 582 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberType *) { 583 return IrInstructionIdMemberType; 584 } 585 586 static constexpr IrInstructionId ir_instruction_id(IrInstructionMemberName *) { 587 return IrInstructionIdMemberName; 588 } 589 590 static constexpr IrInstructionId ir_instruction_id(IrInstructionBreakpoint *) { 591 return IrInstructionIdBreakpoint; 592 } 593 594 static constexpr IrInstructionId ir_instruction_id(IrInstructionReturnAddress *) { 595 return IrInstructionIdReturnAddress; 596 } 597 598 static constexpr IrInstructionId ir_instruction_id(IrInstructionFrameAddress *) { 599 return IrInstructionIdFrameAddress; 600 } 601 602 static constexpr IrInstructionId ir_instruction_id(IrInstructionHandle *) { 603 return IrInstructionIdHandle; 604 } 605 606 static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignOf *) { 607 return IrInstructionIdAlignOf; 608 } 609 610 static constexpr IrInstructionId ir_instruction_id(IrInstructionOverflowOp *) { 611 return IrInstructionIdOverflowOp; 612 } 613 614 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestErr *) { 615 return IrInstructionIdTestErr; 616 } 617 618 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrCode *) { 619 return IrInstructionIdUnwrapErrCode; 620 } 621 622 static constexpr IrInstructionId ir_instruction_id(IrInstructionUnwrapErrPayload *) { 623 return IrInstructionIdUnwrapErrPayload; 624 } 625 626 static constexpr IrInstructionId ir_instruction_id(IrInstructionOptionalWrap *) { 627 return IrInstructionIdOptionalWrap; 628 } 629 630 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapPayload *) { 631 return IrInstructionIdErrWrapPayload; 632 } 633 634 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrWrapCode *) { 635 return IrInstructionIdErrWrapCode; 636 } 637 638 static constexpr IrInstructionId ir_instruction_id(IrInstructionFnProto *) { 639 return IrInstructionIdFnProto; 640 } 641 642 static constexpr IrInstructionId ir_instruction_id(IrInstructionTestComptime *) { 643 return IrInstructionIdTestComptime; 644 } 645 646 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrCast *) { 647 return IrInstructionIdPtrCast; 648 } 649 650 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitCast *) { 651 return IrInstructionIdBitCast; 652 } 653 654 static constexpr IrInstructionId ir_instruction_id(IrInstructionWidenOrShorten *) { 655 return IrInstructionIdWidenOrShorten; 656 } 657 658 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrToInt *) { 659 return IrInstructionIdPtrToInt; 660 } 661 662 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToPtr *) { 663 return IrInstructionIdIntToPtr; 664 } 665 666 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToEnum *) { 667 return IrInstructionIdIntToEnum; 668 } 669 670 static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumToInt *) { 671 return IrInstructionIdEnumToInt; 672 } 673 674 static constexpr IrInstructionId ir_instruction_id(IrInstructionIntToErr *) { 675 return IrInstructionIdIntToErr; 676 } 677 678 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrToInt *) { 679 return IrInstructionIdErrToInt; 680 } 681 682 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckSwitchProngs *) { 683 return IrInstructionIdCheckSwitchProngs; 684 } 685 686 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckStatementIsVoid *) { 687 return IrInstructionIdCheckStatementIsVoid; 688 } 689 690 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeName *) { 691 return IrInstructionIdTypeName; 692 } 693 694 static constexpr IrInstructionId ir_instruction_id(IrInstructionDeclRef *) { 695 return IrInstructionIdDeclRef; 696 } 697 698 static constexpr IrInstructionId ir_instruction_id(IrInstructionPanic *) { 699 return IrInstructionIdPanic; 700 } 701 702 static constexpr IrInstructionId ir_instruction_id(IrInstructionTagName *) { 703 return IrInstructionIdTagName; 704 } 705 706 static constexpr IrInstructionId ir_instruction_id(IrInstructionTagType *) { 707 return IrInstructionIdTagType; 708 } 709 710 static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) { 711 return IrInstructionIdFieldParentPtr; 712 } 713 714 static constexpr IrInstructionId ir_instruction_id(IrInstructionByteOffsetOf *) { 715 return IrInstructionIdByteOffsetOf; 716 } 717 718 static constexpr IrInstructionId ir_instruction_id(IrInstructionBitOffsetOf *) { 719 return IrInstructionIdBitOffsetOf; 720 } 721 722 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { 723 return IrInstructionIdTypeInfo; 724 } 725 726 static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { 727 return IrInstructionIdTypeId; 728 } 729 730 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetEvalBranchQuota *) { 731 return IrInstructionIdSetEvalBranchQuota; 732 } 733 734 static constexpr IrInstructionId ir_instruction_id(IrInstructionPtrType *) { 735 return IrInstructionIdPtrType; 736 } 737 738 static constexpr IrInstructionId ir_instruction_id(IrInstructionAlignCast *) { 739 return IrInstructionIdAlignCast; 740 } 741 742 static constexpr IrInstructionId ir_instruction_id(IrInstructionOpaqueType *) { 743 return IrInstructionIdOpaqueType; 744 } 745 746 static constexpr IrInstructionId ir_instruction_id(IrInstructionSetAlignStack *) { 747 return IrInstructionIdSetAlignStack; 748 } 749 750 static constexpr IrInstructionId ir_instruction_id(IrInstructionArgType *) { 751 return IrInstructionIdArgType; 752 } 753 754 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorReturnTrace *) { 755 return IrInstructionIdErrorReturnTrace; 756 } 757 758 static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorUnion *) { 759 return IrInstructionIdErrorUnion; 760 } 761 762 static constexpr IrInstructionId ir_instruction_id(IrInstructionCancel *) { 763 return IrInstructionIdCancel; 764 } 765 766 static constexpr IrInstructionId ir_instruction_id(IrInstructionGetImplicitAllocator *) { 767 return IrInstructionIdGetImplicitAllocator; 768 } 769 770 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroId *) { 771 return IrInstructionIdCoroId; 772 } 773 774 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAlloc *) { 775 return IrInstructionIdCoroAlloc; 776 } 777 778 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSize *) { 779 return IrInstructionIdCoroSize; 780 } 781 782 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroBegin *) { 783 return IrInstructionIdCoroBegin; 784 } 785 786 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocFail *) { 787 return IrInstructionIdCoroAllocFail; 788 } 789 790 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSuspend *) { 791 return IrInstructionIdCoroSuspend; 792 } 793 794 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroEnd *) { 795 return IrInstructionIdCoroEnd; 796 } 797 798 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroFree *) { 799 return IrInstructionIdCoroFree; 800 } 801 802 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroResume *) { 803 return IrInstructionIdCoroResume; 804 } 805 806 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroSave *) { 807 return IrInstructionIdCoroSave; 808 } 809 810 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroPromise *) { 811 return IrInstructionIdCoroPromise; 812 } 813 814 static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocHelper *) { 815 return IrInstructionIdCoroAllocHelper; 816 } 817 818 static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicRmw *) { 819 return IrInstructionIdAtomicRmw; 820 } 821 822 static constexpr IrInstructionId ir_instruction_id(IrInstructionAtomicLoad *) { 823 return IrInstructionIdAtomicLoad; 824 } 825 826 static constexpr IrInstructionId ir_instruction_id(IrInstructionPromiseResultType *) { 827 return IrInstructionIdPromiseResultType; 828 } 829 830 static constexpr IrInstructionId ir_instruction_id(IrInstructionAwaitBookkeeping *) { 831 return IrInstructionIdAwaitBookkeeping; 832 } 833 834 static constexpr IrInstructionId ir_instruction_id(IrInstructionSaveErrRetAddr *) { 835 return IrInstructionIdSaveErrRetAddr; 836 } 837 838 static constexpr IrInstructionId ir_instruction_id(IrInstructionAddImplicitReturnType *) { 839 return IrInstructionIdAddImplicitReturnType; 840 } 841 842 static constexpr IrInstructionId ir_instruction_id(IrInstructionMergeErrRetTraces *) { 843 return IrInstructionIdMergeErrRetTraces; 844 } 845 846 static constexpr IrInstructionId ir_instruction_id(IrInstructionMarkErrRetTracePtr *) { 847 return IrInstructionIdMarkErrRetTracePtr; 848 } 849 850 static constexpr IrInstructionId ir_instruction_id(IrInstructionSqrt *) { 851 return IrInstructionIdSqrt; 852 } 853 854 static constexpr IrInstructionId ir_instruction_id(IrInstructionCheckRuntimeScope *) { 855 return IrInstructionIdCheckRuntimeScope; 856 } 857 858 template<typename T> 859 static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { 860 T *special_instruction = allocate<T>(1); 861 special_instruction->base.id = ir_instruction_id(special_instruction); 862 special_instruction->base.scope = scope; 863 special_instruction->base.source_node = source_node; 864 special_instruction->base.debug_id = exec_next_debug_id(irb->exec); 865 special_instruction->base.owner_bb = irb->current_basic_block; 866 special_instruction->base.value.global_refs = allocate<ConstGlobalRefs>(1); 867 return special_instruction; 868 } 869 870 template<typename T> 871 static T *ir_build_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { 872 T *special_instruction = ir_create_instruction<T>(irb, scope, source_node); 873 ir_instruction_append(irb->current_basic_block, &special_instruction->base); 874 return special_instruction; 875 } 876 877 static IrInstruction *ir_build_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigType *dest_type, 878 IrInstruction *value, CastOp cast_op) 879 { 880 IrInstructionCast *cast_instruction = ir_build_instruction<IrInstructionCast>(irb, scope, source_node); 881 cast_instruction->dest_type = dest_type; 882 cast_instruction->value = value; 883 cast_instruction->cast_op = cast_op; 884 885 ir_ref_instruction(value, irb->current_basic_block); 886 887 return &cast_instruction->base; 888 } 889 890 static IrInstruction *ir_build_cond_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *condition, 891 IrBasicBlock *then_block, IrBasicBlock *else_block, IrInstruction *is_comptime) 892 { 893 IrInstructionCondBr *cond_br_instruction = ir_build_instruction<IrInstructionCondBr>(irb, scope, source_node); 894 cond_br_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 895 cond_br_instruction->base.value.special = ConstValSpecialStatic; 896 cond_br_instruction->condition = condition; 897 cond_br_instruction->then_block = then_block; 898 cond_br_instruction->else_block = else_block; 899 cond_br_instruction->is_comptime = is_comptime; 900 901 ir_ref_instruction(condition, irb->current_basic_block); 902 ir_ref_bb(then_block); 903 ir_ref_bb(else_block); 904 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 905 906 return &cond_br_instruction->base; 907 } 908 909 static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *return_value) { 910 IrInstructionReturn *return_instruction = ir_build_instruction<IrInstructionReturn>(irb, scope, source_node); 911 return_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 912 return_instruction->base.value.special = ConstValSpecialStatic; 913 return_instruction->value = return_value; 914 915 ir_ref_instruction(return_value, irb->current_basic_block); 916 917 return &return_instruction->base; 918 } 919 920 static IrInstruction *ir_create_const(IrBuilder *irb, Scope *scope, AstNode *source_node, 921 ZigType *type_entry) 922 { 923 assert(type_entry); 924 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 925 const_instruction->base.value.type = type_entry; 926 const_instruction->base.value.special = ConstValSpecialStatic; 927 return &const_instruction->base; 928 } 929 930 static IrInstruction *ir_build_const_void(IrBuilder *irb, Scope *scope, AstNode *source_node) { 931 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 932 const_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 933 const_instruction->base.value.special = ConstValSpecialStatic; 934 return &const_instruction->base; 935 } 936 937 static IrInstruction *ir_build_const_undefined(IrBuilder *irb, Scope *scope, AstNode *source_node) { 938 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 939 const_instruction->base.value.special = ConstValSpecialUndef; 940 const_instruction->base.value.type = irb->codegen->builtin_types.entry_undef; 941 return &const_instruction->base; 942 } 943 944 static IrInstruction *ir_build_const_uint(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { 945 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 946 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_int; 947 const_instruction->base.value.special = ConstValSpecialStatic; 948 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); 949 return &const_instruction->base; 950 } 951 952 static IrInstruction *ir_build_const_bigint(IrBuilder *irb, Scope *scope, AstNode *source_node, BigInt *bigint) { 953 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 954 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_int; 955 const_instruction->base.value.special = ConstValSpecialStatic; 956 bigint_init_bigint(&const_instruction->base.value.data.x_bigint, bigint); 957 return &const_instruction->base; 958 } 959 960 static IrInstruction *ir_build_const_bigfloat(IrBuilder *irb, Scope *scope, AstNode *source_node, BigFloat *bigfloat) { 961 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 962 const_instruction->base.value.type = irb->codegen->builtin_types.entry_num_lit_float; 963 const_instruction->base.value.special = ConstValSpecialStatic; 964 bigfloat_init_bigfloat(&const_instruction->base.value.data.x_bigfloat, bigfloat); 965 return &const_instruction->base; 966 } 967 968 static IrInstruction *ir_build_const_null(IrBuilder *irb, Scope *scope, AstNode *source_node) { 969 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 970 const_instruction->base.value.type = irb->codegen->builtin_types.entry_null; 971 const_instruction->base.value.special = ConstValSpecialStatic; 972 return &const_instruction->base; 973 } 974 975 static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode *source_node, uint64_t value) { 976 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 977 const_instruction->base.value.type = irb->codegen->builtin_types.entry_usize; 978 const_instruction->base.value.special = ConstValSpecialStatic; 979 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); 980 return &const_instruction->base; 981 } 982 983 static IrInstruction *ir_build_const_u8(IrBuilder *irb, Scope *scope, AstNode *source_node, uint8_t value) { 984 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 985 const_instruction->base.value.type = irb->codegen->builtin_types.entry_u8; 986 const_instruction->base.value.special = ConstValSpecialStatic; 987 bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value); 988 return &const_instruction->base; 989 } 990 991 static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 992 ZigType *type_entry) 993 { 994 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 995 const_instruction->base.value.type = irb->codegen->builtin_types.entry_type; 996 const_instruction->base.value.special = ConstValSpecialStatic; 997 const_instruction->base.value.data.x_type = type_entry; 998 return &const_instruction->base; 999 } 1000 1001 static IrInstruction *ir_build_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1002 ZigType *type_entry) 1003 { 1004 IrInstruction *instruction = ir_create_const_type(irb, scope, source_node, type_entry); 1005 ir_instruction_append(irb->current_basic_block, instruction); 1006 return instruction; 1007 } 1008 1009 static IrInstruction *ir_create_const_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigFn *fn_entry) { 1010 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1011 const_instruction->base.value.type = fn_entry->type_entry; 1012 const_instruction->base.value.special = ConstValSpecialStatic; 1013 const_instruction->base.value.data.x_ptr.data.fn.fn_entry = fn_entry; 1014 const_instruction->base.value.data.x_ptr.mut = ConstPtrMutComptimeConst; 1015 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialFunction; 1016 return &const_instruction->base; 1017 } 1018 1019 static IrInstruction *ir_build_const_import(IrBuilder *irb, Scope *scope, AstNode *source_node, ImportTableEntry *import) { 1020 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1021 const_instruction->base.value.type = irb->codegen->builtin_types.entry_namespace; 1022 const_instruction->base.value.special = ConstValSpecialStatic; 1023 const_instruction->base.value.data.x_import = import; 1024 return &const_instruction->base; 1025 } 1026 1027 static IrInstruction *ir_build_const_bool(IrBuilder *irb, Scope *scope, AstNode *source_node, bool value) { 1028 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1029 const_instruction->base.value.type = irb->codegen->builtin_types.entry_bool; 1030 const_instruction->base.value.special = ConstValSpecialStatic; 1031 const_instruction->base.value.data.x_bool = value; 1032 return &const_instruction->base; 1033 } 1034 1035 static IrInstruction *ir_build_const_bound_fn(IrBuilder *irb, Scope *scope, AstNode *source_node, 1036 ZigFn *fn_entry, IrInstruction *first_arg) 1037 { 1038 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1039 const_instruction->base.value.type = get_bound_fn_type(irb->codegen, fn_entry); 1040 const_instruction->base.value.special = ConstValSpecialStatic; 1041 const_instruction->base.value.data.x_bound_fn.fn = fn_entry; 1042 const_instruction->base.value.data.x_bound_fn.first_arg = first_arg; 1043 return &const_instruction->base; 1044 } 1045 1046 static IrInstruction *ir_create_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1047 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(irb, scope, source_node); 1048 init_const_str_lit(irb->codegen, &const_instruction->base.value, str); 1049 1050 return &const_instruction->base; 1051 } 1052 static IrInstruction *ir_build_const_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1053 IrInstruction *instruction = ir_create_const_str_lit(irb, scope, source_node, str); 1054 ir_instruction_append(irb->current_basic_block, instruction); 1055 return instruction; 1056 } 1057 1058 static IrInstruction *ir_build_const_c_str_lit(IrBuilder *irb, Scope *scope, AstNode *source_node, Buf *str) { 1059 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); 1060 init_const_c_str_lit(irb->codegen, &const_instruction->base.value, str); 1061 return &const_instruction->base; 1062 } 1063 1064 static IrInstruction *ir_build_bin_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrBinOp op_id, 1065 IrInstruction *op1, IrInstruction *op2, bool safety_check_on) 1066 { 1067 IrInstructionBinOp *bin_op_instruction = ir_build_instruction<IrInstructionBinOp>(irb, scope, source_node); 1068 bin_op_instruction->op_id = op_id; 1069 bin_op_instruction->op1 = op1; 1070 bin_op_instruction->op2 = op2; 1071 bin_op_instruction->safety_check_on = safety_check_on; 1072 1073 ir_ref_instruction(op1, irb->current_basic_block); 1074 ir_ref_instruction(op2, irb->current_basic_block); 1075 1076 return &bin_op_instruction->base; 1077 } 1078 1079 static IrInstruction *ir_build_var_ptr_x(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var, 1080 ScopeFnDef *crossed_fndef_scope) 1081 { 1082 IrInstructionVarPtr *instruction = ir_build_instruction<IrInstructionVarPtr>(irb, scope, source_node); 1083 instruction->var = var; 1084 instruction->crossed_fndef_scope = crossed_fndef_scope; 1085 1086 ir_ref_var(var); 1087 1088 return &instruction->base; 1089 } 1090 1091 static IrInstruction *ir_build_var_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigVar *var) { 1092 return ir_build_var_ptr_x(irb, scope, source_node, var, nullptr); 1093 } 1094 1095 static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_ptr, 1096 IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len) 1097 { 1098 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node); 1099 instruction->array_ptr = array_ptr; 1100 instruction->elem_index = elem_index; 1101 instruction->safety_check_on = safety_check_on; 1102 instruction->ptr_len = ptr_len; 1103 1104 ir_ref_instruction(array_ptr, irb->current_basic_block); 1105 ir_ref_instruction(elem_index, irb->current_basic_block); 1106 1107 return &instruction->base; 1108 } 1109 1110 static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node, 1111 IrInstruction *container_ptr, IrInstruction *field_name_expr) 1112 { 1113 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); 1114 instruction->container_ptr = container_ptr; 1115 instruction->field_name_buffer = nullptr; 1116 instruction->field_name_expr = field_name_expr; 1117 1118 ir_ref_instruction(container_ptr, irb->current_basic_block); 1119 ir_ref_instruction(field_name_expr, irb->current_basic_block); 1120 1121 return &instruction->base; 1122 } 1123 1124 static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1125 IrInstruction *container_ptr, Buf *field_name) 1126 { 1127 IrInstructionFieldPtr *instruction = ir_build_instruction<IrInstructionFieldPtr>(irb, scope, source_node); 1128 instruction->container_ptr = container_ptr; 1129 instruction->field_name_buffer = field_name; 1130 instruction->field_name_expr = nullptr; 1131 1132 ir_ref_instruction(container_ptr, irb->current_basic_block); 1133 1134 return &instruction->base; 1135 } 1136 1137 static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1138 IrInstruction *struct_ptr, TypeStructField *field) 1139 { 1140 IrInstructionStructFieldPtr *instruction = ir_build_instruction<IrInstructionStructFieldPtr>(irb, scope, source_node); 1141 instruction->struct_ptr = struct_ptr; 1142 instruction->field = field; 1143 1144 ir_ref_instruction(struct_ptr, irb->current_basic_block); 1145 1146 return &instruction->base; 1147 } 1148 1149 static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1150 IrInstruction *union_ptr, TypeUnionField *field) 1151 { 1152 IrInstructionUnionFieldPtr *instruction = ir_build_instruction<IrInstructionUnionFieldPtr>(irb, scope, source_node); 1153 instruction->union_ptr = union_ptr; 1154 instruction->field = field; 1155 1156 ir_ref_instruction(union_ptr, irb->current_basic_block); 1157 1158 return &instruction->base; 1159 } 1160 1161 static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node, 1162 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, 1163 bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, 1164 IrInstruction *new_stack) 1165 { 1166 IrInstructionCall *call_instruction = ir_build_instruction<IrInstructionCall>(irb, scope, source_node); 1167 call_instruction->fn_entry = fn_entry; 1168 call_instruction->fn_ref = fn_ref; 1169 call_instruction->is_comptime = is_comptime; 1170 call_instruction->fn_inline = fn_inline; 1171 call_instruction->args = args; 1172 call_instruction->arg_count = arg_count; 1173 call_instruction->is_async = is_async; 1174 call_instruction->async_allocator = async_allocator; 1175 call_instruction->new_stack = new_stack; 1176 1177 if (fn_ref) 1178 ir_ref_instruction(fn_ref, irb->current_basic_block); 1179 for (size_t i = 0; i < arg_count; i += 1) 1180 ir_ref_instruction(args[i], irb->current_basic_block); 1181 if (async_allocator) 1182 ir_ref_instruction(async_allocator, irb->current_basic_block); 1183 if (new_stack != nullptr) 1184 ir_ref_instruction(new_stack, irb->current_basic_block); 1185 1186 return &call_instruction->base; 1187 } 1188 1189 static IrInstruction *ir_build_phi(IrBuilder *irb, Scope *scope, AstNode *source_node, 1190 size_t incoming_count, IrBasicBlock **incoming_blocks, IrInstruction **incoming_values) 1191 { 1192 assert(incoming_count != 0); 1193 assert(incoming_count != SIZE_MAX); 1194 1195 IrInstructionPhi *phi_instruction = ir_build_instruction<IrInstructionPhi>(irb, scope, source_node); 1196 phi_instruction->incoming_count = incoming_count; 1197 phi_instruction->incoming_blocks = incoming_blocks; 1198 phi_instruction->incoming_values = incoming_values; 1199 1200 for (size_t i = 0; i < incoming_count; i += 1) { 1201 ir_ref_bb(incoming_blocks[i]); 1202 ir_ref_instruction(incoming_values[i], irb->current_basic_block); 1203 } 1204 1205 return &phi_instruction->base; 1206 } 1207 1208 static IrInstruction *ir_create_br(IrBuilder *irb, Scope *scope, AstNode *source_node, 1209 IrBasicBlock *dest_block, IrInstruction *is_comptime) 1210 { 1211 IrInstructionBr *br_instruction = ir_create_instruction<IrInstructionBr>(irb, scope, source_node); 1212 br_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1213 br_instruction->base.value.special = ConstValSpecialStatic; 1214 br_instruction->dest_block = dest_block; 1215 br_instruction->is_comptime = is_comptime; 1216 1217 ir_ref_bb(dest_block); 1218 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 1219 1220 return &br_instruction->base; 1221 } 1222 1223 static IrInstruction *ir_build_br(IrBuilder *irb, Scope *scope, AstNode *source_node, 1224 IrBasicBlock *dest_block, IrInstruction *is_comptime) 1225 { 1226 IrInstruction *instruction = ir_create_br(irb, scope, source_node, dest_block, is_comptime); 1227 ir_instruction_append(irb->current_basic_block, instruction); 1228 return instruction; 1229 } 1230 1231 static IrInstruction *ir_build_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1232 IrInstruction *child_type, bool is_const, bool is_volatile, PtrLen ptr_len, 1233 IrInstruction *align_value, uint32_t bit_offset_start, uint32_t host_int_bytes) 1234 { 1235 IrInstructionPtrType *ptr_type_of_instruction = ir_build_instruction<IrInstructionPtrType>(irb, scope, source_node); 1236 ptr_type_of_instruction->align_value = align_value; 1237 ptr_type_of_instruction->child_type = child_type; 1238 ptr_type_of_instruction->is_const = is_const; 1239 ptr_type_of_instruction->is_volatile = is_volatile; 1240 ptr_type_of_instruction->ptr_len = ptr_len; 1241 ptr_type_of_instruction->bit_offset_start = bit_offset_start; 1242 ptr_type_of_instruction->host_int_bytes = host_int_bytes; 1243 1244 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 1245 ir_ref_instruction(child_type, irb->current_basic_block); 1246 1247 return &ptr_type_of_instruction->base; 1248 } 1249 1250 static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *source_node, IrUnOp op_id, IrInstruction *value) { 1251 IrInstructionUnOp *br_instruction = ir_build_instruction<IrInstructionUnOp>(irb, scope, source_node); 1252 br_instruction->op_id = op_id; 1253 br_instruction->value = value; 1254 1255 ir_ref_instruction(value, irb->current_basic_block); 1256 1257 return &br_instruction->base; 1258 } 1259 1260 static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node, 1261 IrInstruction *container_type, size_t item_count, IrInstruction **items) 1262 { 1263 IrInstructionContainerInitList *container_init_list_instruction = 1264 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node); 1265 container_init_list_instruction->container_type = container_type; 1266 container_init_list_instruction->item_count = item_count; 1267 container_init_list_instruction->items = items; 1268 1269 ir_ref_instruction(container_type, irb->current_basic_block); 1270 for (size_t i = 0; i < item_count; i += 1) { 1271 ir_ref_instruction(items[i], irb->current_basic_block); 1272 } 1273 1274 return &container_init_list_instruction->base; 1275 } 1276 1277 static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node, 1278 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields) 1279 { 1280 IrInstructionContainerInitFields *container_init_fields_instruction = 1281 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node); 1282 container_init_fields_instruction->container_type = container_type; 1283 container_init_fields_instruction->field_count = field_count; 1284 container_init_fields_instruction->fields = fields; 1285 1286 ir_ref_instruction(container_type, irb->current_basic_block); 1287 for (size_t i = 0; i < field_count; i += 1) { 1288 ir_ref_instruction(fields[i].value, irb->current_basic_block); 1289 } 1290 1291 return &container_init_fields_instruction->base; 1292 } 1293 1294 static IrInstruction *ir_build_struct_init(IrBuilder *irb, Scope *scope, AstNode *source_node, 1295 ZigType *struct_type, size_t field_count, IrInstructionStructInitField *fields) 1296 { 1297 IrInstructionStructInit *struct_init_instruction = ir_build_instruction<IrInstructionStructInit>(irb, scope, source_node); 1298 struct_init_instruction->struct_type = struct_type; 1299 struct_init_instruction->field_count = field_count; 1300 struct_init_instruction->fields = fields; 1301 1302 for (size_t i = 0; i < field_count; i += 1) 1303 ir_ref_instruction(fields[i].value, irb->current_basic_block); 1304 1305 return &struct_init_instruction->base; 1306 } 1307 1308 static IrInstruction *ir_build_union_init(IrBuilder *irb, Scope *scope, AstNode *source_node, 1309 ZigType *union_type, TypeUnionField *field, IrInstruction *init_value) 1310 { 1311 IrInstructionUnionInit *union_init_instruction = ir_build_instruction<IrInstructionUnionInit>(irb, scope, source_node); 1312 union_init_instruction->union_type = union_type; 1313 union_init_instruction->field = field; 1314 union_init_instruction->init_value = init_value; 1315 1316 ir_ref_instruction(init_value, irb->current_basic_block); 1317 1318 return &union_init_instruction->base; 1319 } 1320 1321 static IrInstruction *ir_build_unreachable(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1322 IrInstructionUnreachable *unreachable_instruction = 1323 ir_build_instruction<IrInstructionUnreachable>(irb, scope, source_node); 1324 unreachable_instruction->base.value.special = ConstValSpecialStatic; 1325 unreachable_instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1326 return &unreachable_instruction->base; 1327 } 1328 1329 static IrInstruction *ir_build_store_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 1330 IrInstruction *ptr, IrInstruction *value) 1331 { 1332 IrInstructionStorePtr *instruction = ir_build_instruction<IrInstructionStorePtr>(irb, scope, source_node); 1333 instruction->base.value.special = ConstValSpecialStatic; 1334 instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1335 instruction->ptr = ptr; 1336 instruction->value = value; 1337 1338 ir_ref_instruction(ptr, irb->current_basic_block); 1339 ir_ref_instruction(value, irb->current_basic_block); 1340 1341 return &instruction->base; 1342 } 1343 1344 static IrInstruction *ir_build_var_decl(IrBuilder *irb, Scope *scope, AstNode *source_node, 1345 ZigVar *var, IrInstruction *var_type, IrInstruction *align_value, IrInstruction *init_value) 1346 { 1347 IrInstructionDeclVar *decl_var_instruction = ir_build_instruction<IrInstructionDeclVar>(irb, scope, source_node); 1348 decl_var_instruction->base.value.special = ConstValSpecialStatic; 1349 decl_var_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1350 decl_var_instruction->var = var; 1351 decl_var_instruction->var_type = var_type; 1352 decl_var_instruction->align_value = align_value; 1353 decl_var_instruction->init_value = init_value; 1354 1355 if (var_type) ir_ref_instruction(var_type, irb->current_basic_block); 1356 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 1357 ir_ref_instruction(init_value, irb->current_basic_block); 1358 1359 return &decl_var_instruction->base; 1360 } 1361 1362 static IrInstruction *ir_build_export(IrBuilder *irb, Scope *scope, AstNode *source_node, 1363 IrInstruction *name, IrInstruction *target, IrInstruction *linkage) 1364 { 1365 IrInstructionExport *export_instruction = ir_build_instruction<IrInstructionExport>( 1366 irb, scope, source_node); 1367 export_instruction->base.value.special = ConstValSpecialStatic; 1368 export_instruction->base.value.type = irb->codegen->builtin_types.entry_void; 1369 export_instruction->name = name; 1370 export_instruction->target = target; 1371 export_instruction->linkage = linkage; 1372 1373 ir_ref_instruction(name, irb->current_basic_block); 1374 ir_ref_instruction(target, irb->current_basic_block); 1375 if (linkage) ir_ref_instruction(linkage, irb->current_basic_block); 1376 1377 return &export_instruction->base; 1378 } 1379 1380 static IrInstruction *ir_build_load_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *ptr) { 1381 IrInstructionLoadPtr *instruction = ir_build_instruction<IrInstructionLoadPtr>(irb, scope, source_node); 1382 instruction->ptr = ptr; 1383 1384 ir_ref_instruction(ptr, irb->current_basic_block); 1385 1386 return &instruction->base; 1387 } 1388 1389 static IrInstruction *ir_build_typeof(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1390 IrInstructionTypeOf *instruction = ir_build_instruction<IrInstructionTypeOf>(irb, scope, source_node); 1391 instruction->value = value; 1392 1393 ir_ref_instruction(value, irb->current_basic_block); 1394 1395 return &instruction->base; 1396 } 1397 1398 static IrInstruction *ir_build_to_ptr_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1399 IrInstructionToPtrType *instruction = ir_build_instruction<IrInstructionToPtrType>(irb, scope, source_node); 1400 instruction->value = value; 1401 1402 ir_ref_instruction(value, irb->current_basic_block); 1403 1404 return &instruction->base; 1405 } 1406 1407 static IrInstruction *ir_build_ptr_type_child(IrBuilder *irb, Scope *scope, AstNode *source_node, 1408 IrInstruction *value) 1409 { 1410 IrInstructionPtrTypeChild *instruction = ir_build_instruction<IrInstructionPtrTypeChild>( 1411 irb, scope, source_node); 1412 instruction->value = value; 1413 1414 ir_ref_instruction(value, irb->current_basic_block); 1415 1416 return &instruction->base; 1417 } 1418 1419 static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_cold) { 1420 IrInstructionSetCold *instruction = ir_build_instruction<IrInstructionSetCold>(irb, scope, source_node); 1421 instruction->is_cold = is_cold; 1422 1423 ir_ref_instruction(is_cold, irb->current_basic_block); 1424 1425 return &instruction->base; 1426 } 1427 1428 static IrInstruction *ir_build_set_runtime_safety(IrBuilder *irb, Scope *scope, AstNode *source_node, 1429 IrInstruction *safety_on) 1430 { 1431 IrInstructionSetRuntimeSafety *instruction = ir_build_instruction<IrInstructionSetRuntimeSafety>(irb, scope, source_node); 1432 instruction->safety_on = safety_on; 1433 1434 ir_ref_instruction(safety_on, irb->current_basic_block); 1435 1436 return &instruction->base; 1437 } 1438 1439 static IrInstruction *ir_build_set_float_mode(IrBuilder *irb, Scope *scope, AstNode *source_node, 1440 IrInstruction *mode_value) 1441 { 1442 IrInstructionSetFloatMode *instruction = ir_build_instruction<IrInstructionSetFloatMode>(irb, scope, source_node); 1443 instruction->mode_value = mode_value; 1444 1445 ir_ref_instruction(mode_value, irb->current_basic_block); 1446 1447 return &instruction->base; 1448 } 1449 1450 static IrInstruction *ir_build_array_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *size, 1451 IrInstruction *child_type) 1452 { 1453 IrInstructionArrayType *instruction = ir_build_instruction<IrInstructionArrayType>(irb, scope, source_node); 1454 instruction->size = size; 1455 instruction->child_type = child_type; 1456 1457 ir_ref_instruction(size, irb->current_basic_block); 1458 ir_ref_instruction(child_type, irb->current_basic_block); 1459 1460 return &instruction->base; 1461 } 1462 1463 static IrInstruction *ir_build_promise_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1464 IrInstruction *payload_type) 1465 { 1466 IrInstructionPromiseType *instruction = ir_build_instruction<IrInstructionPromiseType>(irb, scope, source_node); 1467 instruction->payload_type = payload_type; 1468 1469 if (payload_type != nullptr) ir_ref_instruction(payload_type, irb->current_basic_block); 1470 1471 return &instruction->base; 1472 } 1473 1474 static IrInstruction *ir_build_slice_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1475 IrInstruction *child_type, bool is_const, bool is_volatile, IrInstruction *align_value) 1476 { 1477 IrInstructionSliceType *instruction = ir_build_instruction<IrInstructionSliceType>(irb, scope, source_node); 1478 instruction->is_const = is_const; 1479 instruction->is_volatile = is_volatile; 1480 instruction->child_type = child_type; 1481 instruction->align_value = align_value; 1482 1483 ir_ref_instruction(child_type, irb->current_basic_block); 1484 if (align_value) ir_ref_instruction(align_value, irb->current_basic_block); 1485 1486 return &instruction->base; 1487 } 1488 1489 static IrInstruction *ir_build_asm(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction **input_list, 1490 IrInstruction **output_types, ZigVar **output_vars, size_t return_count, bool has_side_effects) 1491 { 1492 IrInstructionAsm *instruction = ir_build_instruction<IrInstructionAsm>(irb, scope, source_node); 1493 instruction->input_list = input_list; 1494 instruction->output_types = output_types; 1495 instruction->output_vars = output_vars; 1496 instruction->return_count = return_count; 1497 instruction->has_side_effects = has_side_effects; 1498 1499 assert(source_node->type == NodeTypeAsmExpr); 1500 for (size_t i = 0; i < source_node->data.asm_expr.output_list.length; i += 1) { 1501 IrInstruction *output_type = output_types[i]; 1502 if (output_type) ir_ref_instruction(output_type, irb->current_basic_block); 1503 } 1504 1505 for (size_t i = 0; i < source_node->data.asm_expr.input_list.length; i += 1) { 1506 IrInstruction *input_value = input_list[i]; 1507 ir_ref_instruction(input_value, irb->current_basic_block); 1508 } 1509 1510 return &instruction->base; 1511 } 1512 1513 static IrInstruction *ir_build_size_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { 1514 IrInstructionSizeOf *instruction = ir_build_instruction<IrInstructionSizeOf>(irb, scope, source_node); 1515 instruction->type_value = type_value; 1516 1517 ir_ref_instruction(type_value, irb->current_basic_block); 1518 1519 return &instruction->base; 1520 } 1521 1522 static IrInstruction *ir_build_test_nonnull(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1523 IrInstructionTestNonNull *instruction = ir_build_instruction<IrInstructionTestNonNull>(irb, scope, source_node); 1524 instruction->value = value; 1525 1526 ir_ref_instruction(value, irb->current_basic_block); 1527 1528 return &instruction->base; 1529 } 1530 1531 static IrInstruction *ir_build_unwrap_maybe(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value, 1532 bool safety_check_on) 1533 { 1534 IrInstructionUnwrapOptional *instruction = ir_build_instruction<IrInstructionUnwrapOptional>(irb, scope, source_node); 1535 instruction->value = value; 1536 instruction->safety_check_on = safety_check_on; 1537 1538 ir_ref_instruction(value, irb->current_basic_block); 1539 1540 return &instruction->base; 1541 } 1542 1543 static IrInstruction *ir_build_maybe_wrap(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1544 IrInstructionOptionalWrap *instruction = ir_build_instruction<IrInstructionOptionalWrap>(irb, scope, source_node); 1545 instruction->value = value; 1546 1547 ir_ref_instruction(value, irb->current_basic_block); 1548 1549 return &instruction->base; 1550 } 1551 1552 static IrInstruction *ir_build_err_wrap_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1553 IrInstructionErrWrapPayload *instruction = ir_build_instruction<IrInstructionErrWrapPayload>(irb, scope, source_node); 1554 instruction->value = value; 1555 1556 ir_ref_instruction(value, irb->current_basic_block); 1557 1558 return &instruction->base; 1559 } 1560 1561 static IrInstruction *ir_build_err_wrap_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1562 IrInstructionErrWrapCode *instruction = ir_build_instruction<IrInstructionErrWrapCode>(irb, scope, source_node); 1563 instruction->value = value; 1564 1565 ir_ref_instruction(value, irb->current_basic_block); 1566 1567 return &instruction->base; 1568 } 1569 1570 static IrInstruction *ir_build_clz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1571 IrInstructionClz *instruction = ir_build_instruction<IrInstructionClz>(irb, scope, source_node); 1572 instruction->value = value; 1573 1574 ir_ref_instruction(value, irb->current_basic_block); 1575 1576 return &instruction->base; 1577 } 1578 1579 static IrInstruction *ir_build_ctz(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1580 IrInstructionCtz *instruction = ir_build_instruction<IrInstructionCtz>(irb, scope, source_node); 1581 instruction->value = value; 1582 1583 ir_ref_instruction(value, irb->current_basic_block); 1584 1585 return &instruction->base; 1586 } 1587 1588 static IrInstruction *ir_build_pop_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1589 IrInstructionPopCount *instruction = ir_build_instruction<IrInstructionPopCount>(irb, scope, source_node); 1590 instruction->value = value; 1591 1592 ir_ref_instruction(value, irb->current_basic_block); 1593 1594 return &instruction->base; 1595 } 1596 1597 static IrInstruction *ir_build_switch_br(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target_value, 1598 IrBasicBlock *else_block, size_t case_count, IrInstructionSwitchBrCase *cases, IrInstruction *is_comptime, 1599 IrInstruction *switch_prongs_void) 1600 { 1601 IrInstructionSwitchBr *instruction = ir_build_instruction<IrInstructionSwitchBr>(irb, scope, source_node); 1602 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 1603 instruction->base.value.special = ConstValSpecialStatic; 1604 instruction->target_value = target_value; 1605 instruction->else_block = else_block; 1606 instruction->case_count = case_count; 1607 instruction->cases = cases; 1608 instruction->is_comptime = is_comptime; 1609 instruction->switch_prongs_void = switch_prongs_void; 1610 1611 ir_ref_instruction(target_value, irb->current_basic_block); 1612 if (is_comptime) ir_ref_instruction(is_comptime, irb->current_basic_block); 1613 ir_ref_bb(else_block); 1614 if (switch_prongs_void) ir_ref_instruction(switch_prongs_void, irb->current_basic_block); 1615 1616 for (size_t i = 0; i < case_count; i += 1) { 1617 ir_ref_instruction(cases[i].value, irb->current_basic_block); 1618 ir_ref_bb(cases[i].block); 1619 } 1620 1621 return &instruction->base; 1622 } 1623 1624 static IrInstruction *ir_build_switch_target(IrBuilder *irb, Scope *scope, AstNode *source_node, 1625 IrInstruction *target_value_ptr) 1626 { 1627 IrInstructionSwitchTarget *instruction = ir_build_instruction<IrInstructionSwitchTarget>(irb, scope, source_node); 1628 instruction->target_value_ptr = target_value_ptr; 1629 1630 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 1631 1632 return &instruction->base; 1633 } 1634 1635 static IrInstruction *ir_build_switch_var(IrBuilder *irb, Scope *scope, AstNode *source_node, 1636 IrInstruction *target_value_ptr, IrInstruction *prong_value) 1637 { 1638 IrInstructionSwitchVar *instruction = ir_build_instruction<IrInstructionSwitchVar>(irb, scope, source_node); 1639 instruction->target_value_ptr = target_value_ptr; 1640 instruction->prong_value = prong_value; 1641 1642 ir_ref_instruction(target_value_ptr, irb->current_basic_block); 1643 ir_ref_instruction(prong_value, irb->current_basic_block); 1644 1645 return &instruction->base; 1646 } 1647 1648 static IrInstruction *ir_build_union_tag(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1649 IrInstructionUnionTag *instruction = ir_build_instruction<IrInstructionUnionTag>(irb, scope, source_node); 1650 instruction->value = value; 1651 1652 ir_ref_instruction(value, irb->current_basic_block); 1653 1654 return &instruction->base; 1655 } 1656 1657 static IrInstruction *ir_build_import(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1658 IrInstructionImport *instruction = ir_build_instruction<IrInstructionImport>(irb, scope, source_node); 1659 instruction->name = name; 1660 1661 ir_ref_instruction(name, irb->current_basic_block); 1662 1663 return &instruction->base; 1664 } 1665 1666 static IrInstruction *ir_build_array_len(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *array_value) { 1667 IrInstructionArrayLen *instruction = ir_build_instruction<IrInstructionArrayLen>(irb, scope, source_node); 1668 instruction->array_value = array_value; 1669 1670 ir_ref_instruction(array_value, irb->current_basic_block); 1671 1672 return &instruction->base; 1673 } 1674 1675 static IrInstruction *ir_build_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value, 1676 bool is_const, bool is_volatile) 1677 { 1678 IrInstructionRef *instruction = ir_build_instruction<IrInstructionRef>(irb, scope, source_node); 1679 instruction->value = value; 1680 instruction->is_const = is_const; 1681 instruction->is_volatile = is_volatile; 1682 1683 ir_ref_instruction(value, irb->current_basic_block); 1684 1685 return &instruction->base; 1686 } 1687 1688 static IrInstruction *ir_build_compile_err(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { 1689 IrInstructionCompileErr *instruction = ir_build_instruction<IrInstructionCompileErr>(irb, scope, source_node); 1690 instruction->msg = msg; 1691 1692 ir_ref_instruction(msg, irb->current_basic_block); 1693 1694 return &instruction->base; 1695 } 1696 1697 static IrInstruction *ir_build_compile_log(IrBuilder *irb, Scope *scope, AstNode *source_node, 1698 size_t msg_count, IrInstruction **msg_list) 1699 { 1700 IrInstructionCompileLog *instruction = ir_build_instruction<IrInstructionCompileLog>(irb, scope, source_node); 1701 instruction->msg_count = msg_count; 1702 instruction->msg_list = msg_list; 1703 1704 for (size_t i = 0; i < msg_count; i += 1) { 1705 ir_ref_instruction(msg_list[i], irb->current_basic_block); 1706 } 1707 1708 return &instruction->base; 1709 } 1710 1711 static IrInstruction *ir_build_err_name(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1712 IrInstructionErrName *instruction = ir_build_instruction<IrInstructionErrName>(irb, scope, source_node); 1713 instruction->value = value; 1714 1715 ir_ref_instruction(value, irb->current_basic_block); 1716 1717 return &instruction->base; 1718 } 1719 1720 static IrInstruction *ir_build_c_import(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1721 IrInstructionCImport *instruction = ir_build_instruction<IrInstructionCImport>(irb, scope, source_node); 1722 return &instruction->base; 1723 } 1724 1725 static IrInstruction *ir_build_c_include(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1726 IrInstructionCInclude *instruction = ir_build_instruction<IrInstructionCInclude>(irb, scope, source_node); 1727 instruction->name = name; 1728 1729 ir_ref_instruction(name, irb->current_basic_block); 1730 1731 return &instruction->base; 1732 } 1733 1734 static IrInstruction *ir_build_c_define(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name, IrInstruction *value) { 1735 IrInstructionCDefine *instruction = ir_build_instruction<IrInstructionCDefine>(irb, scope, source_node); 1736 instruction->name = name; 1737 instruction->value = value; 1738 1739 ir_ref_instruction(name, irb->current_basic_block); 1740 ir_ref_instruction(value, irb->current_basic_block); 1741 1742 return &instruction->base; 1743 } 1744 1745 static IrInstruction *ir_build_c_undef(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1746 IrInstructionCUndef *instruction = ir_build_instruction<IrInstructionCUndef>(irb, scope, source_node); 1747 instruction->name = name; 1748 1749 ir_ref_instruction(name, irb->current_basic_block); 1750 1751 return &instruction->base; 1752 } 1753 1754 static IrInstruction *ir_build_embed_file(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *name) { 1755 IrInstructionEmbedFile *instruction = ir_build_instruction<IrInstructionEmbedFile>(irb, scope, source_node); 1756 instruction->name = name; 1757 1758 ir_ref_instruction(name, irb->current_basic_block); 1759 1760 return &instruction->base; 1761 } 1762 1763 static IrInstruction *ir_build_cmpxchg(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value, 1764 IrInstruction *ptr, IrInstruction *cmp_value, IrInstruction *new_value, 1765 IrInstruction *success_order_value, IrInstruction *failure_order_value, 1766 bool is_weak, 1767 ZigType *type, AtomicOrder success_order, AtomicOrder failure_order) 1768 { 1769 IrInstructionCmpxchg *instruction = ir_build_instruction<IrInstructionCmpxchg>(irb, scope, source_node); 1770 instruction->type_value = type_value; 1771 instruction->ptr = ptr; 1772 instruction->cmp_value = cmp_value; 1773 instruction->new_value = new_value; 1774 instruction->success_order_value = success_order_value; 1775 instruction->failure_order_value = failure_order_value; 1776 instruction->is_weak = is_weak; 1777 instruction->type = type; 1778 instruction->success_order = success_order; 1779 instruction->failure_order = failure_order; 1780 1781 if (type_value != nullptr) ir_ref_instruction(type_value, irb->current_basic_block); 1782 ir_ref_instruction(ptr, irb->current_basic_block); 1783 ir_ref_instruction(cmp_value, irb->current_basic_block); 1784 ir_ref_instruction(new_value, irb->current_basic_block); 1785 if (type_value != nullptr) ir_ref_instruction(success_order_value, irb->current_basic_block); 1786 if (type_value != nullptr) ir_ref_instruction(failure_order_value, irb->current_basic_block); 1787 1788 return &instruction->base; 1789 } 1790 1791 static IrInstruction *ir_build_fence(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *order_value, AtomicOrder order) { 1792 IrInstructionFence *instruction = ir_build_instruction<IrInstructionFence>(irb, scope, source_node); 1793 instruction->order_value = order_value; 1794 instruction->order = order; 1795 1796 ir_ref_instruction(order_value, irb->current_basic_block); 1797 1798 return &instruction->base; 1799 } 1800 1801 static IrInstruction *ir_build_truncate(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 1802 IrInstructionTruncate *instruction = ir_build_instruction<IrInstructionTruncate>(irb, scope, source_node); 1803 instruction->dest_type = dest_type; 1804 instruction->target = target; 1805 1806 ir_ref_instruction(dest_type, irb->current_basic_block); 1807 ir_ref_instruction(target, irb->current_basic_block); 1808 1809 return &instruction->base; 1810 } 1811 1812 static IrInstruction *ir_build_int_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 1813 IrInstructionIntCast *instruction = ir_build_instruction<IrInstructionIntCast>(irb, scope, source_node); 1814 instruction->dest_type = dest_type; 1815 instruction->target = target; 1816 1817 ir_ref_instruction(dest_type, irb->current_basic_block); 1818 ir_ref_instruction(target, irb->current_basic_block); 1819 1820 return &instruction->base; 1821 } 1822 1823 static IrInstruction *ir_build_float_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 1824 IrInstructionFloatCast *instruction = ir_build_instruction<IrInstructionFloatCast>(irb, scope, source_node); 1825 instruction->dest_type = dest_type; 1826 instruction->target = target; 1827 1828 ir_ref_instruction(dest_type, irb->current_basic_block); 1829 ir_ref_instruction(target, irb->current_basic_block); 1830 1831 return &instruction->base; 1832 } 1833 1834 static IrInstruction *ir_build_err_set_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 1835 IrInstructionErrSetCast *instruction = ir_build_instruction<IrInstructionErrSetCast>(irb, scope, source_node); 1836 instruction->dest_type = dest_type; 1837 instruction->target = target; 1838 1839 ir_ref_instruction(dest_type, irb->current_basic_block); 1840 ir_ref_instruction(target, irb->current_basic_block); 1841 1842 return &instruction->base; 1843 } 1844 1845 static IrInstruction *ir_build_to_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { 1846 IrInstructionToBytes *instruction = ir_build_instruction<IrInstructionToBytes>(irb, scope, source_node); 1847 instruction->target = target; 1848 1849 ir_ref_instruction(target, irb->current_basic_block); 1850 1851 return &instruction->base; 1852 } 1853 1854 static IrInstruction *ir_build_from_bytes(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_child_type, IrInstruction *target) { 1855 IrInstructionFromBytes *instruction = ir_build_instruction<IrInstructionFromBytes>(irb, scope, source_node); 1856 instruction->dest_child_type = dest_child_type; 1857 instruction->target = target; 1858 1859 ir_ref_instruction(dest_child_type, irb->current_basic_block); 1860 ir_ref_instruction(target, irb->current_basic_block); 1861 1862 return &instruction->base; 1863 } 1864 1865 static IrInstruction *ir_build_int_to_float(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 1866 IrInstructionIntToFloat *instruction = ir_build_instruction<IrInstructionIntToFloat>(irb, scope, source_node); 1867 instruction->dest_type = dest_type; 1868 instruction->target = target; 1869 1870 ir_ref_instruction(dest_type, irb->current_basic_block); 1871 ir_ref_instruction(target, irb->current_basic_block); 1872 1873 return &instruction->base; 1874 } 1875 1876 static IrInstruction *ir_build_float_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *dest_type, IrInstruction *target) { 1877 IrInstructionFloatToInt *instruction = ir_build_instruction<IrInstructionFloatToInt>(irb, scope, source_node); 1878 instruction->dest_type = dest_type; 1879 instruction->target = target; 1880 1881 ir_ref_instruction(dest_type, irb->current_basic_block); 1882 ir_ref_instruction(target, irb->current_basic_block); 1883 1884 return &instruction->base; 1885 } 1886 1887 static IrInstruction *ir_build_bool_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *target) { 1888 IrInstructionBoolToInt *instruction = ir_build_instruction<IrInstructionBoolToInt>(irb, scope, source_node); 1889 instruction->target = target; 1890 1891 ir_ref_instruction(target, irb->current_basic_block); 1892 1893 return &instruction->base; 1894 } 1895 1896 static IrInstruction *ir_build_int_type(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *is_signed, IrInstruction *bit_count) { 1897 IrInstructionIntType *instruction = ir_build_instruction<IrInstructionIntType>(irb, scope, source_node); 1898 instruction->is_signed = is_signed; 1899 instruction->bit_count = bit_count; 1900 1901 ir_ref_instruction(is_signed, irb->current_basic_block); 1902 ir_ref_instruction(bit_count, irb->current_basic_block); 1903 1904 return &instruction->base; 1905 } 1906 1907 static IrInstruction *ir_build_bool_not(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 1908 IrInstructionBoolNot *instruction = ir_build_instruction<IrInstructionBoolNot>(irb, scope, source_node); 1909 instruction->value = value; 1910 1911 ir_ref_instruction(value, irb->current_basic_block); 1912 1913 return &instruction->base; 1914 } 1915 1916 static IrInstruction *ir_build_memset(IrBuilder *irb, Scope *scope, AstNode *source_node, 1917 IrInstruction *dest_ptr, IrInstruction *byte, IrInstruction *count) 1918 { 1919 IrInstructionMemset *instruction = ir_build_instruction<IrInstructionMemset>(irb, scope, source_node); 1920 instruction->dest_ptr = dest_ptr; 1921 instruction->byte = byte; 1922 instruction->count = count; 1923 1924 ir_ref_instruction(dest_ptr, irb->current_basic_block); 1925 ir_ref_instruction(byte, irb->current_basic_block); 1926 ir_ref_instruction(count, irb->current_basic_block); 1927 1928 return &instruction->base; 1929 } 1930 1931 static IrInstruction *ir_build_memcpy(IrBuilder *irb, Scope *scope, AstNode *source_node, 1932 IrInstruction *dest_ptr, IrInstruction *src_ptr, IrInstruction *count) 1933 { 1934 IrInstructionMemcpy *instruction = ir_build_instruction<IrInstructionMemcpy>(irb, scope, source_node); 1935 instruction->dest_ptr = dest_ptr; 1936 instruction->src_ptr = src_ptr; 1937 instruction->count = count; 1938 1939 ir_ref_instruction(dest_ptr, irb->current_basic_block); 1940 ir_ref_instruction(src_ptr, irb->current_basic_block); 1941 ir_ref_instruction(count, irb->current_basic_block); 1942 1943 return &instruction->base; 1944 } 1945 1946 static IrInstruction *ir_build_slice(IrBuilder *irb, Scope *scope, AstNode *source_node, 1947 IrInstruction *ptr, IrInstruction *start, IrInstruction *end, bool safety_check_on) 1948 { 1949 IrInstructionSlice *instruction = ir_build_instruction<IrInstructionSlice>(irb, scope, source_node); 1950 instruction->ptr = ptr; 1951 instruction->start = start; 1952 instruction->end = end; 1953 instruction->safety_check_on = safety_check_on; 1954 1955 ir_ref_instruction(ptr, irb->current_basic_block); 1956 ir_ref_instruction(start, irb->current_basic_block); 1957 if (end) ir_ref_instruction(end, irb->current_basic_block); 1958 1959 return &instruction->base; 1960 } 1961 1962 static IrInstruction *ir_build_member_count(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *container) { 1963 IrInstructionMemberCount *instruction = ir_build_instruction<IrInstructionMemberCount>(irb, scope, source_node); 1964 instruction->container = container; 1965 1966 ir_ref_instruction(container, irb->current_basic_block); 1967 1968 return &instruction->base; 1969 } 1970 1971 static IrInstruction *ir_build_member_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 1972 IrInstruction *container_type, IrInstruction *member_index) 1973 { 1974 IrInstructionMemberType *instruction = ir_build_instruction<IrInstructionMemberType>(irb, scope, source_node); 1975 instruction->container_type = container_type; 1976 instruction->member_index = member_index; 1977 1978 ir_ref_instruction(container_type, irb->current_basic_block); 1979 ir_ref_instruction(member_index, irb->current_basic_block); 1980 1981 return &instruction->base; 1982 } 1983 1984 static IrInstruction *ir_build_member_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 1985 IrInstruction *container_type, IrInstruction *member_index) 1986 { 1987 IrInstructionMemberName *instruction = ir_build_instruction<IrInstructionMemberName>(irb, scope, source_node); 1988 instruction->container_type = container_type; 1989 instruction->member_index = member_index; 1990 1991 ir_ref_instruction(container_type, irb->current_basic_block); 1992 ir_ref_instruction(member_index, irb->current_basic_block); 1993 1994 return &instruction->base; 1995 } 1996 1997 static IrInstruction *ir_build_breakpoint(IrBuilder *irb, Scope *scope, AstNode *source_node) { 1998 IrInstructionBreakpoint *instruction = ir_build_instruction<IrInstructionBreakpoint>(irb, scope, source_node); 1999 return &instruction->base; 2000 } 2001 2002 static IrInstruction *ir_build_return_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2003 IrInstructionReturnAddress *instruction = ir_build_instruction<IrInstructionReturnAddress>(irb, scope, source_node); 2004 return &instruction->base; 2005 } 2006 2007 static IrInstruction *ir_build_frame_address(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2008 IrInstructionFrameAddress *instruction = ir_build_instruction<IrInstructionFrameAddress>(irb, scope, source_node); 2009 return &instruction->base; 2010 } 2011 2012 static IrInstruction *ir_build_handle(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2013 IrInstructionHandle *instruction = ir_build_instruction<IrInstructionHandle>(irb, scope, source_node); 2014 return &instruction->base; 2015 } 2016 2017 static IrInstruction *ir_build_overflow_op(IrBuilder *irb, Scope *scope, AstNode *source_node, 2018 IrOverflowOp op, IrInstruction *type_value, IrInstruction *op1, IrInstruction *op2, 2019 IrInstruction *result_ptr, ZigType *result_ptr_type) 2020 { 2021 IrInstructionOverflowOp *instruction = ir_build_instruction<IrInstructionOverflowOp>(irb, scope, source_node); 2022 instruction->op = op; 2023 instruction->type_value = type_value; 2024 instruction->op1 = op1; 2025 instruction->op2 = op2; 2026 instruction->result_ptr = result_ptr; 2027 instruction->result_ptr_type = result_ptr_type; 2028 2029 ir_ref_instruction(type_value, irb->current_basic_block); 2030 ir_ref_instruction(op1, irb->current_basic_block); 2031 ir_ref_instruction(op2, irb->current_basic_block); 2032 ir_ref_instruction(result_ptr, irb->current_basic_block); 2033 2034 return &instruction->base; 2035 } 2036 2037 static IrInstruction *ir_build_align_of(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type_value) { 2038 IrInstructionAlignOf *instruction = ir_build_instruction<IrInstructionAlignOf>(irb, scope, source_node); 2039 instruction->type_value = type_value; 2040 2041 ir_ref_instruction(type_value, irb->current_basic_block); 2042 2043 return &instruction->base; 2044 } 2045 2046 static IrInstruction *ir_build_test_err(IrBuilder *irb, Scope *scope, AstNode *source_node, 2047 IrInstruction *value) 2048 { 2049 IrInstructionTestErr *instruction = ir_build_instruction<IrInstructionTestErr>(irb, scope, source_node); 2050 instruction->value = value; 2051 2052 ir_ref_instruction(value, irb->current_basic_block); 2053 2054 return &instruction->base; 2055 } 2056 2057 static IrInstruction *ir_build_unwrap_err_code(IrBuilder *irb, Scope *scope, AstNode *source_node, 2058 IrInstruction *value) 2059 { 2060 IrInstructionUnwrapErrCode *instruction = ir_build_instruction<IrInstructionUnwrapErrCode>(irb, scope, source_node); 2061 instruction->value = value; 2062 2063 ir_ref_instruction(value, irb->current_basic_block); 2064 2065 return &instruction->base; 2066 } 2067 2068 static IrInstruction *ir_build_unwrap_err_payload(IrBuilder *irb, Scope *scope, AstNode *source_node, 2069 IrInstruction *value, bool safety_check_on) 2070 { 2071 IrInstructionUnwrapErrPayload *instruction = ir_build_instruction<IrInstructionUnwrapErrPayload>(irb, scope, source_node); 2072 instruction->value = value; 2073 instruction->safety_check_on = safety_check_on; 2074 2075 ir_ref_instruction(value, irb->current_basic_block); 2076 2077 return &instruction->base; 2078 } 2079 2080 static IrInstruction *ir_build_fn_proto(IrBuilder *irb, Scope *scope, AstNode *source_node, 2081 IrInstruction **param_types, IrInstruction *align_value, IrInstruction *return_type, 2082 IrInstruction *async_allocator_type_value, bool is_var_args) 2083 { 2084 IrInstructionFnProto *instruction = ir_build_instruction<IrInstructionFnProto>(irb, scope, source_node); 2085 instruction->param_types = param_types; 2086 instruction->align_value = align_value; 2087 instruction->return_type = return_type; 2088 instruction->async_allocator_type_value = async_allocator_type_value; 2089 instruction->is_var_args = is_var_args; 2090 2091 assert(source_node->type == NodeTypeFnProto); 2092 size_t param_count = source_node->data.fn_proto.params.length; 2093 if (is_var_args) param_count -= 1; 2094 for (size_t i = 0; i < param_count; i += 1) { 2095 if (param_types[i] != nullptr) ir_ref_instruction(param_types[i], irb->current_basic_block); 2096 } 2097 if (align_value != nullptr) ir_ref_instruction(align_value, irb->current_basic_block); 2098 if (async_allocator_type_value != nullptr) ir_ref_instruction(async_allocator_type_value, irb->current_basic_block); 2099 ir_ref_instruction(return_type, irb->current_basic_block); 2100 2101 return &instruction->base; 2102 } 2103 2104 static IrInstruction *ir_build_test_comptime(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { 2105 IrInstructionTestComptime *instruction = ir_build_instruction<IrInstructionTestComptime>(irb, scope, source_node); 2106 instruction->value = value; 2107 2108 ir_ref_instruction(value, irb->current_basic_block); 2109 2110 return &instruction->base; 2111 } 2112 2113 static IrInstruction *ir_build_ptr_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 2114 IrInstruction *dest_type, IrInstruction *ptr) 2115 { 2116 IrInstructionPtrCast *instruction = ir_build_instruction<IrInstructionPtrCast>( 2117 irb, scope, source_node); 2118 instruction->dest_type = dest_type; 2119 instruction->ptr = ptr; 2120 2121 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2122 ir_ref_instruction(ptr, irb->current_basic_block); 2123 2124 return &instruction->base; 2125 } 2126 2127 static IrInstruction *ir_build_bit_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 2128 IrInstruction *dest_type, IrInstruction *value) 2129 { 2130 IrInstructionBitCast *instruction = ir_build_instruction<IrInstructionBitCast>( 2131 irb, scope, source_node); 2132 instruction->dest_type = dest_type; 2133 instruction->value = value; 2134 2135 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2136 ir_ref_instruction(value, irb->current_basic_block); 2137 2138 return &instruction->base; 2139 } 2140 2141 static IrInstruction *ir_build_widen_or_shorten(IrBuilder *irb, Scope *scope, AstNode *source_node, 2142 IrInstruction *target) 2143 { 2144 IrInstructionWidenOrShorten *instruction = ir_build_instruction<IrInstructionWidenOrShorten>( 2145 irb, scope, source_node); 2146 instruction->target = target; 2147 2148 ir_ref_instruction(target, irb->current_basic_block); 2149 2150 return &instruction->base; 2151 } 2152 2153 static IrInstruction *ir_build_int_to_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 2154 IrInstruction *dest_type, IrInstruction *target) 2155 { 2156 IrInstructionIntToPtr *instruction = ir_build_instruction<IrInstructionIntToPtr>( 2157 irb, scope, source_node); 2158 instruction->dest_type = dest_type; 2159 instruction->target = target; 2160 2161 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2162 ir_ref_instruction(target, irb->current_basic_block); 2163 2164 return &instruction->base; 2165 } 2166 2167 static IrInstruction *ir_build_ptr_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2168 IrInstruction *target) 2169 { 2170 IrInstructionPtrToInt *instruction = ir_build_instruction<IrInstructionPtrToInt>( 2171 irb, scope, source_node); 2172 instruction->target = target; 2173 2174 ir_ref_instruction(target, irb->current_basic_block); 2175 2176 return &instruction->base; 2177 } 2178 2179 static IrInstruction *ir_build_int_to_enum(IrBuilder *irb, Scope *scope, AstNode *source_node, 2180 IrInstruction *dest_type, IrInstruction *target) 2181 { 2182 IrInstructionIntToEnum *instruction = ir_build_instruction<IrInstructionIntToEnum>( 2183 irb, scope, source_node); 2184 instruction->dest_type = dest_type; 2185 instruction->target = target; 2186 2187 if (dest_type) ir_ref_instruction(dest_type, irb->current_basic_block); 2188 ir_ref_instruction(target, irb->current_basic_block); 2189 2190 return &instruction->base; 2191 } 2192 2193 2194 2195 static IrInstruction *ir_build_enum_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2196 IrInstruction *target) 2197 { 2198 IrInstructionEnumToInt *instruction = ir_build_instruction<IrInstructionEnumToInt>( 2199 irb, scope, source_node); 2200 instruction->target = target; 2201 2202 ir_ref_instruction(target, irb->current_basic_block); 2203 2204 return &instruction->base; 2205 } 2206 2207 static IrInstruction *ir_build_int_to_err(IrBuilder *irb, Scope *scope, AstNode *source_node, 2208 IrInstruction *target) 2209 { 2210 IrInstructionIntToErr *instruction = ir_build_instruction<IrInstructionIntToErr>( 2211 irb, scope, source_node); 2212 instruction->target = target; 2213 2214 ir_ref_instruction(target, irb->current_basic_block); 2215 2216 return &instruction->base; 2217 } 2218 2219 static IrInstruction *ir_build_err_to_int(IrBuilder *irb, Scope *scope, AstNode *source_node, 2220 IrInstruction *target) 2221 { 2222 IrInstructionErrToInt *instruction = ir_build_instruction<IrInstructionErrToInt>( 2223 irb, scope, source_node); 2224 instruction->target = target; 2225 2226 ir_ref_instruction(target, irb->current_basic_block); 2227 2228 return &instruction->base; 2229 } 2230 2231 static IrInstruction *ir_build_check_switch_prongs(IrBuilder *irb, Scope *scope, AstNode *source_node, 2232 IrInstruction *target_value, IrInstructionCheckSwitchProngsRange *ranges, size_t range_count, 2233 bool have_else_prong) 2234 { 2235 IrInstructionCheckSwitchProngs *instruction = ir_build_instruction<IrInstructionCheckSwitchProngs>( 2236 irb, scope, source_node); 2237 instruction->target_value = target_value; 2238 instruction->ranges = ranges; 2239 instruction->range_count = range_count; 2240 instruction->have_else_prong = have_else_prong; 2241 2242 ir_ref_instruction(target_value, irb->current_basic_block); 2243 for (size_t i = 0; i < range_count; i += 1) { 2244 ir_ref_instruction(ranges[i].start, irb->current_basic_block); 2245 ir_ref_instruction(ranges[i].end, irb->current_basic_block); 2246 } 2247 2248 return &instruction->base; 2249 } 2250 2251 static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *scope, AstNode *source_node, 2252 IrInstruction* statement_value) 2253 { 2254 IrInstructionCheckStatementIsVoid *instruction = ir_build_instruction<IrInstructionCheckStatementIsVoid>( 2255 irb, scope, source_node); 2256 instruction->statement_value = statement_value; 2257 2258 ir_ref_instruction(statement_value, irb->current_basic_block); 2259 2260 return &instruction->base; 2261 } 2262 2263 static IrInstruction *ir_build_type_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2264 IrInstruction *type_value) 2265 { 2266 IrInstructionTypeName *instruction = ir_build_instruction<IrInstructionTypeName>( 2267 irb, scope, source_node); 2268 instruction->type_value = type_value; 2269 2270 ir_ref_instruction(type_value, irb->current_basic_block); 2271 2272 return &instruction->base; 2273 } 2274 2275 static IrInstruction *ir_build_decl_ref(IrBuilder *irb, Scope *scope, AstNode *source_node, 2276 Tld *tld, LVal lval) 2277 { 2278 IrInstructionDeclRef *instruction = ir_build_instruction<IrInstructionDeclRef>( 2279 irb, scope, source_node); 2280 instruction->tld = tld; 2281 instruction->lval = lval; 2282 2283 return &instruction->base; 2284 } 2285 2286 static IrInstruction *ir_build_panic(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *msg) { 2287 IrInstructionPanic *instruction = ir_build_instruction<IrInstructionPanic>(irb, scope, source_node); 2288 instruction->base.value.special = ConstValSpecialStatic; 2289 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 2290 instruction->msg = msg; 2291 2292 ir_ref_instruction(msg, irb->current_basic_block); 2293 2294 return &instruction->base; 2295 } 2296 2297 static IrInstruction *ir_build_tag_name(IrBuilder *irb, Scope *scope, AstNode *source_node, 2298 IrInstruction *target) 2299 { 2300 IrInstructionTagName *instruction = ir_build_instruction<IrInstructionTagName>(irb, scope, source_node); 2301 instruction->target = target; 2302 2303 ir_ref_instruction(target, irb->current_basic_block); 2304 2305 return &instruction->base; 2306 } 2307 2308 static IrInstruction *ir_build_tag_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2309 IrInstruction *target) 2310 { 2311 IrInstructionTagType *instruction = ir_build_instruction<IrInstructionTagType>(irb, scope, source_node); 2312 instruction->target = target; 2313 2314 ir_ref_instruction(target, irb->current_basic_block); 2315 2316 return &instruction->base; 2317 } 2318 2319 static IrInstruction *ir_build_field_parent_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, 2320 IrInstruction *type_value, IrInstruction *field_name, IrInstruction *field_ptr, TypeStructField *field) 2321 { 2322 IrInstructionFieldParentPtr *instruction = ir_build_instruction<IrInstructionFieldParentPtr>( 2323 irb, scope, source_node); 2324 instruction->type_value = type_value; 2325 instruction->field_name = field_name; 2326 instruction->field_ptr = field_ptr; 2327 instruction->field = field; 2328 2329 ir_ref_instruction(type_value, irb->current_basic_block); 2330 ir_ref_instruction(field_name, irb->current_basic_block); 2331 ir_ref_instruction(field_ptr, irb->current_basic_block); 2332 2333 return &instruction->base; 2334 } 2335 2336 static IrInstruction *ir_build_byte_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node, 2337 IrInstruction *type_value, IrInstruction *field_name) 2338 { 2339 IrInstructionByteOffsetOf *instruction = ir_build_instruction<IrInstructionByteOffsetOf>(irb, scope, source_node); 2340 instruction->type_value = type_value; 2341 instruction->field_name = field_name; 2342 2343 ir_ref_instruction(type_value, irb->current_basic_block); 2344 ir_ref_instruction(field_name, irb->current_basic_block); 2345 2346 return &instruction->base; 2347 } 2348 2349 static IrInstruction *ir_build_bit_offset_of(IrBuilder *irb, Scope *scope, AstNode *source_node, 2350 IrInstruction *type_value, IrInstruction *field_name) 2351 { 2352 IrInstructionBitOffsetOf *instruction = ir_build_instruction<IrInstructionBitOffsetOf>(irb, scope, source_node); 2353 instruction->type_value = type_value; 2354 instruction->field_name = field_name; 2355 2356 ir_ref_instruction(type_value, irb->current_basic_block); 2357 ir_ref_instruction(field_name, irb->current_basic_block); 2358 2359 return &instruction->base; 2360 } 2361 2362 static IrInstruction *ir_build_type_info(IrBuilder *irb, Scope *scope, AstNode *source_node, 2363 IrInstruction *type_value) { 2364 IrInstructionTypeInfo *instruction = ir_build_instruction<IrInstructionTypeInfo>(irb, scope, source_node); 2365 instruction->type_value = type_value; 2366 2367 ir_ref_instruction(type_value, irb->current_basic_block); 2368 2369 return &instruction->base; 2370 } 2371 2372 static IrInstruction *ir_build_type_id(IrBuilder *irb, Scope *scope, AstNode *source_node, 2373 IrInstruction *type_value) 2374 { 2375 IrInstructionTypeId *instruction = ir_build_instruction<IrInstructionTypeId>(irb, scope, source_node); 2376 instruction->type_value = type_value; 2377 2378 ir_ref_instruction(type_value, irb->current_basic_block); 2379 2380 return &instruction->base; 2381 } 2382 2383 static IrInstruction *ir_build_set_eval_branch_quota(IrBuilder *irb, Scope *scope, AstNode *source_node, 2384 IrInstruction *new_quota) 2385 { 2386 IrInstructionSetEvalBranchQuota *instruction = ir_build_instruction<IrInstructionSetEvalBranchQuota>(irb, scope, source_node); 2387 instruction->new_quota = new_quota; 2388 2389 ir_ref_instruction(new_quota, irb->current_basic_block); 2390 2391 return &instruction->base; 2392 } 2393 2394 static IrInstruction *ir_build_align_cast(IrBuilder *irb, Scope *scope, AstNode *source_node, 2395 IrInstruction *align_bytes, IrInstruction *target) 2396 { 2397 IrInstructionAlignCast *instruction = ir_build_instruction<IrInstructionAlignCast>(irb, scope, source_node); 2398 instruction->align_bytes = align_bytes; 2399 instruction->target = target; 2400 2401 if (align_bytes) ir_ref_instruction(align_bytes, irb->current_basic_block); 2402 ir_ref_instruction(target, irb->current_basic_block); 2403 2404 return &instruction->base; 2405 } 2406 2407 static IrInstruction *ir_build_opaque_type(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2408 IrInstructionOpaqueType *instruction = ir_build_instruction<IrInstructionOpaqueType>(irb, scope, source_node); 2409 2410 return &instruction->base; 2411 } 2412 2413 static IrInstruction *ir_build_set_align_stack(IrBuilder *irb, Scope *scope, AstNode *source_node, 2414 IrInstruction *align_bytes) 2415 { 2416 IrInstructionSetAlignStack *instruction = ir_build_instruction<IrInstructionSetAlignStack>(irb, scope, source_node); 2417 instruction->align_bytes = align_bytes; 2418 2419 ir_ref_instruction(align_bytes, irb->current_basic_block); 2420 2421 return &instruction->base; 2422 } 2423 2424 static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2425 IrInstruction *fn_type, IrInstruction *arg_index) 2426 { 2427 IrInstructionArgType *instruction = ir_build_instruction<IrInstructionArgType>(irb, scope, source_node); 2428 instruction->fn_type = fn_type; 2429 instruction->arg_index = arg_index; 2430 2431 ir_ref_instruction(fn_type, irb->current_basic_block); 2432 ir_ref_instruction(arg_index, irb->current_basic_block); 2433 2434 return &instruction->base; 2435 } 2436 2437 static IrInstruction *ir_build_error_return_trace(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstructionErrorReturnTrace::Optional optional) { 2438 IrInstructionErrorReturnTrace *instruction = ir_build_instruction<IrInstructionErrorReturnTrace>(irb, scope, source_node); 2439 instruction->optional = optional; 2440 2441 return &instruction->base; 2442 } 2443 2444 static IrInstruction *ir_build_error_union(IrBuilder *irb, Scope *scope, AstNode *source_node, 2445 IrInstruction *err_set, IrInstruction *payload) 2446 { 2447 IrInstructionErrorUnion *instruction = ir_build_instruction<IrInstructionErrorUnion>(irb, scope, source_node); 2448 instruction->err_set = err_set; 2449 instruction->payload = payload; 2450 2451 ir_ref_instruction(err_set, irb->current_basic_block); 2452 ir_ref_instruction(payload, irb->current_basic_block); 2453 2454 return &instruction->base; 2455 } 2456 2457 static IrInstruction *ir_build_cancel(IrBuilder *irb, Scope *scope, AstNode *source_node, 2458 IrInstruction *target) 2459 { 2460 IrInstructionCancel *instruction = ir_build_instruction<IrInstructionCancel>(irb, scope, source_node); 2461 instruction->target = target; 2462 2463 ir_ref_instruction(target, irb->current_basic_block); 2464 2465 return &instruction->base; 2466 } 2467 2468 static IrInstruction *ir_build_get_implicit_allocator(IrBuilder *irb, Scope *scope, AstNode *source_node, 2469 ImplicitAllocatorId id) 2470 { 2471 IrInstructionGetImplicitAllocator *instruction = ir_build_instruction<IrInstructionGetImplicitAllocator>(irb, scope, source_node); 2472 instruction->id = id; 2473 2474 return &instruction->base; 2475 } 2476 2477 static IrInstruction *ir_build_coro_id(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *promise_ptr) { 2478 IrInstructionCoroId *instruction = ir_build_instruction<IrInstructionCoroId>(irb, scope, source_node); 2479 instruction->promise_ptr = promise_ptr; 2480 2481 ir_ref_instruction(promise_ptr, irb->current_basic_block); 2482 2483 return &instruction->base; 2484 } 2485 2486 static IrInstruction *ir_build_coro_alloc(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id) { 2487 IrInstructionCoroAlloc *instruction = ir_build_instruction<IrInstructionCoroAlloc>(irb, scope, source_node); 2488 instruction->coro_id = coro_id; 2489 2490 ir_ref_instruction(coro_id, irb->current_basic_block); 2491 2492 return &instruction->base; 2493 } 2494 2495 static IrInstruction *ir_build_coro_size(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2496 IrInstructionCoroSize *instruction = ir_build_instruction<IrInstructionCoroSize>(irb, scope, source_node); 2497 2498 return &instruction->base; 2499 } 2500 2501 static IrInstruction *ir_build_coro_begin(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *coro_id, IrInstruction *coro_mem_ptr) { 2502 IrInstructionCoroBegin *instruction = ir_build_instruction<IrInstructionCoroBegin>(irb, scope, source_node); 2503 instruction->coro_id = coro_id; 2504 instruction->coro_mem_ptr = coro_mem_ptr; 2505 2506 ir_ref_instruction(coro_id, irb->current_basic_block); 2507 ir_ref_instruction(coro_mem_ptr, irb->current_basic_block); 2508 2509 return &instruction->base; 2510 } 2511 2512 static IrInstruction *ir_build_coro_alloc_fail(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_val) { 2513 IrInstructionCoroAllocFail *instruction = ir_build_instruction<IrInstructionCoroAllocFail>(irb, scope, source_node); 2514 instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable; 2515 instruction->base.value.special = ConstValSpecialStatic; 2516 instruction->err_val = err_val; 2517 2518 ir_ref_instruction(err_val, irb->current_basic_block); 2519 2520 return &instruction->base; 2521 } 2522 2523 static IrInstruction *ir_build_coro_suspend(IrBuilder *irb, Scope *scope, AstNode *source_node, 2524 IrInstruction *save_point, IrInstruction *is_final) 2525 { 2526 IrInstructionCoroSuspend *instruction = ir_build_instruction<IrInstructionCoroSuspend>(irb, scope, source_node); 2527 instruction->save_point = save_point; 2528 instruction->is_final = is_final; 2529 2530 if (save_point != nullptr) ir_ref_instruction(save_point, irb->current_basic_block); 2531 ir_ref_instruction(is_final, irb->current_basic_block); 2532 2533 return &instruction->base; 2534 } 2535 2536 static IrInstruction *ir_build_coro_end(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2537 IrInstructionCoroEnd *instruction = ir_build_instruction<IrInstructionCoroEnd>(irb, scope, source_node); 2538 return &instruction->base; 2539 } 2540 2541 static IrInstruction *ir_build_coro_free(IrBuilder *irb, Scope *scope, AstNode *source_node, 2542 IrInstruction *coro_id, IrInstruction *coro_handle) 2543 { 2544 IrInstructionCoroFree *instruction = ir_build_instruction<IrInstructionCoroFree>(irb, scope, source_node); 2545 instruction->coro_id = coro_id; 2546 instruction->coro_handle = coro_handle; 2547 2548 ir_ref_instruction(coro_id, irb->current_basic_block); 2549 ir_ref_instruction(coro_handle, irb->current_basic_block); 2550 2551 return &instruction->base; 2552 } 2553 2554 static IrInstruction *ir_build_coro_resume(IrBuilder *irb, Scope *scope, AstNode *source_node, 2555 IrInstruction *awaiter_handle) 2556 { 2557 IrInstructionCoroResume *instruction = ir_build_instruction<IrInstructionCoroResume>(irb, scope, source_node); 2558 instruction->awaiter_handle = awaiter_handle; 2559 2560 ir_ref_instruction(awaiter_handle, irb->current_basic_block); 2561 2562 return &instruction->base; 2563 } 2564 2565 static IrInstruction *ir_build_coro_save(IrBuilder *irb, Scope *scope, AstNode *source_node, 2566 IrInstruction *coro_handle) 2567 { 2568 IrInstructionCoroSave *instruction = ir_build_instruction<IrInstructionCoroSave>(irb, scope, source_node); 2569 instruction->coro_handle = coro_handle; 2570 2571 ir_ref_instruction(coro_handle, irb->current_basic_block); 2572 2573 return &instruction->base; 2574 } 2575 2576 static IrInstruction *ir_build_coro_promise(IrBuilder *irb, Scope *scope, AstNode *source_node, 2577 IrInstruction *coro_handle) 2578 { 2579 IrInstructionCoroPromise *instruction = ir_build_instruction<IrInstructionCoroPromise>(irb, scope, source_node); 2580 instruction->coro_handle = coro_handle; 2581 2582 ir_ref_instruction(coro_handle, irb->current_basic_block); 2583 2584 return &instruction->base; 2585 } 2586 2587 static IrInstruction *ir_build_coro_alloc_helper(IrBuilder *irb, Scope *scope, AstNode *source_node, 2588 IrInstruction *alloc_fn, IrInstruction *coro_size) 2589 { 2590 IrInstructionCoroAllocHelper *instruction = ir_build_instruction<IrInstructionCoroAllocHelper>(irb, scope, source_node); 2591 instruction->alloc_fn = alloc_fn; 2592 instruction->coro_size = coro_size; 2593 2594 ir_ref_instruction(alloc_fn, irb->current_basic_block); 2595 ir_ref_instruction(coro_size, irb->current_basic_block); 2596 2597 return &instruction->base; 2598 } 2599 2600 static IrInstruction *ir_build_atomic_rmw(IrBuilder *irb, Scope *scope, AstNode *source_node, 2601 IrInstruction *operand_type, IrInstruction *ptr, IrInstruction *op, IrInstruction *operand, 2602 IrInstruction *ordering, AtomicRmwOp resolved_op, AtomicOrder resolved_ordering) 2603 { 2604 IrInstructionAtomicRmw *instruction = ir_build_instruction<IrInstructionAtomicRmw>(irb, scope, source_node); 2605 instruction->operand_type = operand_type; 2606 instruction->ptr = ptr; 2607 instruction->op = op; 2608 instruction->operand = operand; 2609 instruction->ordering = ordering; 2610 instruction->resolved_op = resolved_op; 2611 instruction->resolved_ordering = resolved_ordering; 2612 2613 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); 2614 ir_ref_instruction(ptr, irb->current_basic_block); 2615 if (op != nullptr) ir_ref_instruction(op, irb->current_basic_block); 2616 ir_ref_instruction(operand, irb->current_basic_block); 2617 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); 2618 2619 return &instruction->base; 2620 } 2621 2622 static IrInstruction *ir_build_atomic_load(IrBuilder *irb, Scope *scope, AstNode *source_node, 2623 IrInstruction *operand_type, IrInstruction *ptr, 2624 IrInstruction *ordering, AtomicOrder resolved_ordering) 2625 { 2626 IrInstructionAtomicLoad *instruction = ir_build_instruction<IrInstructionAtomicLoad>(irb, scope, source_node); 2627 instruction->operand_type = operand_type; 2628 instruction->ptr = ptr; 2629 instruction->ordering = ordering; 2630 instruction->resolved_ordering = resolved_ordering; 2631 2632 if (operand_type != nullptr) ir_ref_instruction(operand_type, irb->current_basic_block); 2633 ir_ref_instruction(ptr, irb->current_basic_block); 2634 if (ordering != nullptr) ir_ref_instruction(ordering, irb->current_basic_block); 2635 2636 return &instruction->base; 2637 } 2638 2639 static IrInstruction *ir_build_promise_result_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2640 IrInstruction *promise_type) 2641 { 2642 IrInstructionPromiseResultType *instruction = ir_build_instruction<IrInstructionPromiseResultType>(irb, scope, source_node); 2643 instruction->promise_type = promise_type; 2644 2645 ir_ref_instruction(promise_type, irb->current_basic_block); 2646 2647 return &instruction->base; 2648 } 2649 2650 static IrInstruction *ir_build_await_bookkeeping(IrBuilder *irb, Scope *scope, AstNode *source_node, 2651 IrInstruction *promise_result_type) 2652 { 2653 IrInstructionAwaitBookkeeping *instruction = ir_build_instruction<IrInstructionAwaitBookkeeping>(irb, scope, source_node); 2654 instruction->promise_result_type = promise_result_type; 2655 2656 ir_ref_instruction(promise_result_type, irb->current_basic_block); 2657 2658 return &instruction->base; 2659 } 2660 2661 static IrInstruction *ir_build_save_err_ret_addr(IrBuilder *irb, Scope *scope, AstNode *source_node) { 2662 IrInstructionSaveErrRetAddr *instruction = ir_build_instruction<IrInstructionSaveErrRetAddr>(irb, scope, source_node); 2663 return &instruction->base; 2664 } 2665 2666 static IrInstruction *ir_build_add_implicit_return_type(IrBuilder *irb, Scope *scope, AstNode *source_node, 2667 IrInstruction *value) 2668 { 2669 IrInstructionAddImplicitReturnType *instruction = ir_build_instruction<IrInstructionAddImplicitReturnType>(irb, scope, source_node); 2670 instruction->value = value; 2671 2672 ir_ref_instruction(value, irb->current_basic_block); 2673 2674 return &instruction->base; 2675 } 2676 2677 static IrInstruction *ir_build_merge_err_ret_traces(IrBuilder *irb, Scope *scope, AstNode *source_node, 2678 IrInstruction *coro_promise_ptr, IrInstruction *src_err_ret_trace_ptr, IrInstruction *dest_err_ret_trace_ptr) 2679 { 2680 IrInstructionMergeErrRetTraces *instruction = ir_build_instruction<IrInstructionMergeErrRetTraces>(irb, scope, source_node); 2681 instruction->coro_promise_ptr = coro_promise_ptr; 2682 instruction->src_err_ret_trace_ptr = src_err_ret_trace_ptr; 2683 instruction->dest_err_ret_trace_ptr = dest_err_ret_trace_ptr; 2684 2685 ir_ref_instruction(coro_promise_ptr, irb->current_basic_block); 2686 ir_ref_instruction(src_err_ret_trace_ptr, irb->current_basic_block); 2687 ir_ref_instruction(dest_err_ret_trace_ptr, irb->current_basic_block); 2688 2689 return &instruction->base; 2690 } 2691 2692 static IrInstruction *ir_build_mark_err_ret_trace_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_ret_trace_ptr) { 2693 IrInstructionMarkErrRetTracePtr *instruction = ir_build_instruction<IrInstructionMarkErrRetTracePtr>(irb, scope, source_node); 2694 instruction->err_ret_trace_ptr = err_ret_trace_ptr; 2695 2696 ir_ref_instruction(err_ret_trace_ptr, irb->current_basic_block); 2697 2698 return &instruction->base; 2699 } 2700 2701 static IrInstruction *ir_build_sqrt(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *type, IrInstruction *op) { 2702 IrInstructionSqrt *instruction = ir_build_instruction<IrInstructionSqrt>(irb, scope, source_node); 2703 instruction->type = type; 2704 instruction->op = op; 2705 2706 if (type != nullptr) ir_ref_instruction(type, irb->current_basic_block); 2707 ir_ref_instruction(op, irb->current_basic_block); 2708 2709 return &instruction->base; 2710 } 2711 2712 static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *scope_is_comptime, IrInstruction *is_comptime) { 2713 IrInstructionCheckRuntimeScope *instruction = ir_build_instruction<IrInstructionCheckRuntimeScope>(irb, scope, source_node); 2714 instruction->scope_is_comptime = scope_is_comptime; 2715 instruction->is_comptime = is_comptime; 2716 2717 ir_ref_instruction(scope_is_comptime, irb->current_basic_block); 2718 ir_ref_instruction(is_comptime, irb->current_basic_block); 2719 2720 return &instruction->base; 2721 } 2722 2723 static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { 2724 results[ReturnKindUnconditional] = 0; 2725 results[ReturnKindError] = 0; 2726 2727 Scope *scope = inner_scope; 2728 2729 while (scope != outer_scope) { 2730 assert(scope); 2731 switch (scope->id) { 2732 case ScopeIdDefer: { 2733 AstNode *defer_node = scope->source_node; 2734 assert(defer_node->type == NodeTypeDefer); 2735 ReturnKind defer_kind = defer_node->data.defer.kind; 2736 results[defer_kind] += 1; 2737 scope = scope->parent; 2738 continue; 2739 } 2740 case ScopeIdDecls: 2741 case ScopeIdFnDef: 2742 return; 2743 case ScopeIdBlock: 2744 case ScopeIdVarDecl: 2745 case ScopeIdLoop: 2746 case ScopeIdSuspend: 2747 case ScopeIdCompTime: 2748 case ScopeIdRuntime: 2749 scope = scope->parent; 2750 continue; 2751 case ScopeIdDeferExpr: 2752 case ScopeIdCImport: 2753 case ScopeIdCoroPrelude: 2754 zig_unreachable(); 2755 } 2756 } 2757 } 2758 2759 static IrInstruction *ir_mark_gen(IrInstruction *instruction) { 2760 instruction->is_gen = true; 2761 return instruction; 2762 } 2763 2764 static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, bool gen_error_defers) { 2765 Scope *scope = inner_scope; 2766 bool is_noreturn = false; 2767 while (scope != outer_scope) { 2768 if (!scope) 2769 return is_noreturn; 2770 2771 switch (scope->id) { 2772 case ScopeIdDefer: { 2773 AstNode *defer_node = scope->source_node; 2774 assert(defer_node->type == NodeTypeDefer); 2775 ReturnKind defer_kind = defer_node->data.defer.kind; 2776 if (defer_kind == ReturnKindUnconditional || 2777 (gen_error_defers && defer_kind == ReturnKindError)) 2778 { 2779 AstNode *defer_expr_node = defer_node->data.defer.expr; 2780 Scope *defer_expr_scope = defer_node->data.defer.expr_scope; 2781 IrInstruction *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope); 2782 if (defer_expr_value != irb->codegen->invalid_instruction) { 2783 if (defer_expr_value->value.type != nullptr && defer_expr_value->value.type->id == ZigTypeIdUnreachable) { 2784 is_noreturn = true; 2785 } else { 2786 ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, defer_expr_value)); 2787 } 2788 } 2789 } 2790 scope = scope->parent; 2791 continue; 2792 } 2793 case ScopeIdDecls: 2794 case ScopeIdFnDef: 2795 return is_noreturn; 2796 case ScopeIdBlock: 2797 case ScopeIdVarDecl: 2798 case ScopeIdLoop: 2799 case ScopeIdSuspend: 2800 case ScopeIdCompTime: 2801 case ScopeIdRuntime: 2802 scope = scope->parent; 2803 continue; 2804 case ScopeIdDeferExpr: 2805 case ScopeIdCImport: 2806 case ScopeIdCoroPrelude: 2807 zig_unreachable(); 2808 } 2809 } 2810 return is_noreturn; 2811 } 2812 2813 static void ir_set_cursor_at_end(IrBuilder *irb, IrBasicBlock *basic_block) { 2814 assert(basic_block); 2815 2816 irb->current_basic_block = basic_block; 2817 } 2818 2819 static void ir_set_cursor_at_end_and_append_block(IrBuilder *irb, IrBasicBlock *basic_block) { 2820 irb->exec->basic_block_list.append(basic_block); 2821 ir_set_cursor_at_end(irb, basic_block); 2822 } 2823 2824 static ScopeSuspend *get_scope_suspend(Scope *scope) { 2825 while (scope) { 2826 if (scope->id == ScopeIdSuspend) 2827 return (ScopeSuspend *)scope; 2828 if (scope->id == ScopeIdFnDef) 2829 return nullptr; 2830 2831 scope = scope->parent; 2832 } 2833 return nullptr; 2834 } 2835 2836 static ScopeDeferExpr *get_scope_defer_expr(Scope *scope) { 2837 while (scope) { 2838 if (scope->id == ScopeIdDeferExpr) 2839 return (ScopeDeferExpr *)scope; 2840 if (scope->id == ScopeIdFnDef) 2841 return nullptr; 2842 2843 scope = scope->parent; 2844 } 2845 return nullptr; 2846 } 2847 2848 static bool exec_is_async(IrExecutable *exec) { 2849 ZigFn *fn_entry = exec_fn_entry(exec); 2850 return fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; 2851 } 2852 2853 static IrInstruction *ir_gen_async_return(IrBuilder *irb, Scope *scope, AstNode *node, IrInstruction *return_value, 2854 bool is_generated_code) 2855 { 2856 ir_mark_gen(ir_build_add_implicit_return_type(irb, scope, node, return_value)); 2857 2858 bool is_async = exec_is_async(irb->exec); 2859 if (!is_async) { 2860 IrInstruction *return_inst = ir_build_return(irb, scope, node, return_value); 2861 return_inst->is_gen = is_generated_code; 2862 return return_inst; 2863 } 2864 2865 IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "Suspended"); 2866 IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "NotSuspended"); 2867 IrBasicBlock *store_awaiter_block = ir_create_basic_block(irb, scope, "StoreAwaiter"); 2868 IrBasicBlock *check_canceled_block = ir_create_basic_block(irb, scope, "CheckCanceled"); 2869 2870 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 2871 IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 2872 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 2873 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 2874 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); 2875 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); 2876 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 2877 2878 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_field_ptr, return_value); 2879 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 2880 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 2881 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, ptr_mask, nullptr, 2882 AtomicRmwOp_or, AtomicOrderSeqCst); 2883 2884 IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 2885 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 2886 ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime); 2887 2888 ir_set_cursor_at_end_and_append_block(irb, suspended_block); 2889 ir_build_unreachable(irb, scope, node); 2890 2891 ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); 2892 IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 2893 // if we ever add null checking safety to the ptrtoint instruction, it needs to be disabled here 2894 IrInstruction *have_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); 2895 ir_build_cond_br(irb, scope, node, have_await_handle, store_awaiter_block, check_canceled_block, is_comptime); 2896 2897 ir_set_cursor_at_end_and_append_block(irb, store_awaiter_block); 2898 IrInstruction *await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, await_handle_addr); 2899 ir_build_store_ptr(irb, scope, node, irb->exec->await_handle_var_ptr, await_handle); 2900 ir_build_br(irb, scope, node, irb->exec->coro_normal_final, is_comptime); 2901 2902 ir_set_cursor_at_end_and_append_block(irb, check_canceled_block); 2903 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 2904 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 2905 return ir_build_cond_br(irb, scope, node, is_canceled_bool, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, is_comptime); 2906 } 2907 2908 static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 2909 assert(node->type == NodeTypeReturnExpr); 2910 2911 ZigFn *fn_entry = exec_fn_entry(irb->exec); 2912 if (!fn_entry) { 2913 add_node_error(irb->codegen, node, buf_sprintf("return expression outside function definition")); 2914 return irb->codegen->invalid_instruction; 2915 } 2916 2917 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); 2918 if (scope_defer_expr) { 2919 if (!scope_defer_expr->reported_err) { 2920 add_node_error(irb->codegen, node, buf_sprintf("cannot return from defer expression")); 2921 scope_defer_expr->reported_err = true; 2922 } 2923 return irb->codegen->invalid_instruction; 2924 } 2925 2926 Scope *outer_scope = irb->exec->begin_scope; 2927 2928 AstNode *expr_node = node->data.return_expr.expr; 2929 switch (node->data.return_expr.kind) { 2930 case ReturnKindUnconditional: 2931 { 2932 IrInstruction *return_value; 2933 if (expr_node) { 2934 // Temporarily set this so that if we return a type it gets the name of the function 2935 ZigFn *prev_name_fn = irb->exec->name_fn; 2936 irb->exec->name_fn = exec_fn_entry(irb->exec); 2937 return_value = ir_gen_node(irb, expr_node, scope); 2938 irb->exec->name_fn = prev_name_fn; 2939 if (return_value == irb->codegen->invalid_instruction) 2940 return irb->codegen->invalid_instruction; 2941 } else { 2942 return_value = ir_build_const_void(irb, scope, node); 2943 } 2944 2945 size_t defer_counts[2]; 2946 ir_count_defers(irb, scope, outer_scope, defer_counts); 2947 bool have_err_defers = defer_counts[ReturnKindError] > 0; 2948 if (have_err_defers || irb->codegen->have_err_ret_tracing) { 2949 IrBasicBlock *err_block = ir_create_basic_block(irb, scope, "ErrRetErr"); 2950 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "ErrRetOk"); 2951 if (!have_err_defers) { 2952 ir_gen_defers_for_block(irb, scope, outer_scope, false); 2953 } 2954 2955 IrInstruction *is_err = ir_build_test_err(irb, scope, node, return_value); 2956 2957 bool should_inline = ir_should_inline(irb->exec, scope); 2958 IrInstruction *is_comptime; 2959 if (should_inline) { 2960 is_comptime = ir_build_const_bool(irb, scope, node, true); 2961 } else { 2962 is_comptime = ir_build_test_comptime(irb, scope, node, is_err); 2963 } 2964 2965 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err, err_block, ok_block, is_comptime)); 2966 IrBasicBlock *ret_stmt_block = ir_create_basic_block(irb, scope, "RetStmt"); 2967 2968 ir_set_cursor_at_end_and_append_block(irb, err_block); 2969 if (have_err_defers) { 2970 ir_gen_defers_for_block(irb, scope, outer_scope, true); 2971 } 2972 if (irb->codegen->have_err_ret_tracing && !should_inline) { 2973 ir_build_save_err_ret_addr(irb, scope, node); 2974 } 2975 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 2976 2977 ir_set_cursor_at_end_and_append_block(irb, ok_block); 2978 if (have_err_defers) { 2979 ir_gen_defers_for_block(irb, scope, outer_scope, false); 2980 } 2981 ir_build_br(irb, scope, node, ret_stmt_block, is_comptime); 2982 2983 ir_set_cursor_at_end_and_append_block(irb, ret_stmt_block); 2984 return ir_gen_async_return(irb, scope, node, return_value, false); 2985 } else { 2986 // generate unconditional defers 2987 ir_gen_defers_for_block(irb, scope, outer_scope, false); 2988 return ir_gen_async_return(irb, scope, node, return_value, false); 2989 } 2990 } 2991 case ReturnKindError: 2992 { 2993 assert(expr_node); 2994 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 2995 if (err_union_ptr == irb->codegen->invalid_instruction) 2996 return irb->codegen->invalid_instruction; 2997 IrInstruction *err_union_val = ir_build_load_ptr(irb, scope, node, err_union_ptr); 2998 IrInstruction *is_err_val = ir_build_test_err(irb, scope, node, err_union_val); 2999 3000 IrBasicBlock *return_block = ir_create_basic_block(irb, scope, "ErrRetReturn"); 3001 IrBasicBlock *continue_block = ir_create_basic_block(irb, scope, "ErrRetContinue"); 3002 IrInstruction *is_comptime; 3003 bool should_inline = ir_should_inline(irb->exec, scope); 3004 if (should_inline) { 3005 is_comptime = ir_build_const_bool(irb, scope, node, true); 3006 } else { 3007 is_comptime = ir_build_test_comptime(irb, scope, node, is_err_val); 3008 } 3009 ir_mark_gen(ir_build_cond_br(irb, scope, node, is_err_val, return_block, continue_block, is_comptime)); 3010 3011 ir_set_cursor_at_end_and_append_block(irb, return_block); 3012 if (!ir_gen_defers_for_block(irb, scope, outer_scope, true)) { 3013 IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, err_union_ptr); 3014 if (irb->codegen->have_err_ret_tracing && !should_inline) { 3015 ir_build_save_err_ret_addr(irb, scope, node); 3016 } 3017 ir_gen_async_return(irb, scope, node, err_val, false); 3018 } 3019 3020 ir_set_cursor_at_end_and_append_block(irb, continue_block); 3021 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, scope, node, err_union_ptr, false); 3022 if (lval == LValPtr) 3023 return unwrapped_ptr; 3024 else 3025 return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); 3026 } 3027 } 3028 zig_unreachable(); 3029 } 3030 3031 static ZigVar *create_local_var(CodeGen *codegen, AstNode *node, Scope *parent_scope, 3032 Buf *name, bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime, 3033 bool skip_name_check) 3034 { 3035 ZigVar *variable_entry = allocate<ZigVar>(1); 3036 variable_entry->parent_scope = parent_scope; 3037 variable_entry->shadowable = is_shadowable; 3038 variable_entry->mem_slot_index = SIZE_MAX; 3039 variable_entry->is_comptime = is_comptime; 3040 variable_entry->src_arg_index = SIZE_MAX; 3041 variable_entry->value = create_const_vals(1); 3042 3043 if (is_comptime != nullptr) { 3044 is_comptime->ref_count += 1; 3045 } 3046 3047 if (name) { 3048 buf_init_from_buf(&variable_entry->name, name); 3049 3050 if (!skip_name_check) { 3051 ZigVar *existing_var = find_variable(codegen, parent_scope, name, nullptr); 3052 if (existing_var && !existing_var->shadowable) { 3053 ErrorMsg *msg = add_node_error(codegen, node, 3054 buf_sprintf("redeclaration of variable '%s'", buf_ptr(name))); 3055 add_error_note(codegen, msg, existing_var->decl_node, buf_sprintf("previous declaration is here")); 3056 variable_entry->value->type = codegen->builtin_types.entry_invalid; 3057 } else { 3058 ZigType *type; 3059 if (get_primitive_type(codegen, name, &type) != ErrorPrimitiveTypeNotFound) { 3060 add_node_error(codegen, node, 3061 buf_sprintf("variable shadows primitive type '%s'", buf_ptr(name))); 3062 variable_entry->value->type = codegen->builtin_types.entry_invalid; 3063 } else { 3064 Tld *tld = find_decl(codegen, parent_scope, name); 3065 if (tld != nullptr) { 3066 ErrorMsg *msg = add_node_error(codegen, node, 3067 buf_sprintf("redefinition of '%s'", buf_ptr(name))); 3068 add_error_note(codegen, msg, tld->source_node, buf_sprintf("previous definition is here")); 3069 variable_entry->value->type = codegen->builtin_types.entry_invalid; 3070 } 3071 } 3072 } 3073 } 3074 } else { 3075 assert(is_shadowable); 3076 // TODO make this name not actually be in scope. user should be able to make a variable called "_anon" 3077 // might already be solved, let's just make sure it has test coverage 3078 // maybe we put a prefix on this so the debug info doesn't clobber user debug info for same named variables 3079 buf_init_from_str(&variable_entry->name, "_anon"); 3080 } 3081 3082 variable_entry->src_is_const = src_is_const; 3083 variable_entry->gen_is_const = gen_is_const; 3084 variable_entry->decl_node = node; 3085 variable_entry->child_scope = create_var_scope(codegen, node, parent_scope, variable_entry); 3086 3087 return variable_entry; 3088 } 3089 3090 // Set name to nullptr to make the variable anonymous (not visible to programmer). 3091 // After you call this function var->child_scope has the variable in scope 3092 static ZigVar *ir_create_var(IrBuilder *irb, AstNode *node, Scope *scope, Buf *name, 3093 bool src_is_const, bool gen_is_const, bool is_shadowable, IrInstruction *is_comptime) 3094 { 3095 bool is_underscored = name ? buf_eql_str(name, "_") : false; 3096 ZigVar *var = create_local_var(irb->codegen, node, scope, 3097 (is_underscored ? nullptr : name), src_is_const, gen_is_const, 3098 (is_underscored ? true : is_shadowable), is_comptime, false); 3099 if (is_comptime != nullptr || gen_is_const) { 3100 var->mem_slot_index = exec_next_mem_slot(irb->exec); 3101 var->owner_exec = irb->exec; 3102 } 3103 assert(var->child_scope); 3104 return var; 3105 } 3106 3107 static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) { 3108 assert(block_node->type == NodeTypeBlock); 3109 3110 ZigList<IrInstruction *> incoming_values = {0}; 3111 ZigList<IrBasicBlock *> incoming_blocks = {0}; 3112 3113 ScopeBlock *scope_block = create_block_scope(irb->codegen, block_node, parent_scope); 3114 3115 Scope *outer_block_scope = &scope_block->base; 3116 Scope *child_scope = outer_block_scope; 3117 3118 ZigFn *fn_entry = scope_fn_entry(parent_scope); 3119 if (fn_entry && fn_entry->child_scope == parent_scope) { 3120 fn_entry->def_scope = scope_block; 3121 } 3122 3123 if (block_node->data.block.statements.length == 0) { 3124 // {} 3125 return ir_build_const_void(irb, child_scope, block_node); 3126 } 3127 3128 if (block_node->data.block.name != nullptr) { 3129 scope_block->incoming_blocks = &incoming_blocks; 3130 scope_block->incoming_values = &incoming_values; 3131 scope_block->end_block = ir_create_basic_block(irb, parent_scope, "BlockEnd"); 3132 scope_block->is_comptime = ir_build_const_bool(irb, parent_scope, block_node, ir_should_inline(irb->exec, parent_scope)); 3133 } 3134 3135 bool is_continuation_unreachable = false; 3136 IrInstruction *noreturn_return_value = nullptr; 3137 for (size_t i = 0; i < block_node->data.block.statements.length; i += 1) { 3138 AstNode *statement_node = block_node->data.block.statements.at(i); 3139 3140 IrInstruction *statement_value = ir_gen_node(irb, statement_node, child_scope); 3141 is_continuation_unreachable = instr_is_unreachable(statement_value); 3142 if (is_continuation_unreachable) { 3143 // keep the last noreturn statement value around in case we need to return it 3144 noreturn_return_value = statement_value; 3145 } 3146 if (statement_node->type == NodeTypeDefer && statement_value != irb->codegen->invalid_instruction) { 3147 // defer starts a new scope 3148 child_scope = statement_node->data.defer.child_scope; 3149 assert(child_scope); 3150 } else if (statement_value->id == IrInstructionIdDeclVar) { 3151 // variable declarations start a new scope 3152 IrInstructionDeclVar *decl_var_instruction = (IrInstructionDeclVar *)statement_value; 3153 child_scope = decl_var_instruction->var->child_scope; 3154 } else if (statement_value != irb->codegen->invalid_instruction && !is_continuation_unreachable) { 3155 // this statement's value must be void 3156 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, statement_node, statement_value)); 3157 } 3158 } 3159 3160 if (is_continuation_unreachable) { 3161 assert(noreturn_return_value != nullptr); 3162 if (block_node->data.block.name == nullptr || incoming_blocks.length == 0) { 3163 return noreturn_return_value; 3164 } 3165 3166 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 3167 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 3168 } else { 3169 incoming_blocks.append(irb->current_basic_block); 3170 incoming_values.append(ir_mark_gen(ir_build_const_void(irb, parent_scope, block_node))); 3171 } 3172 3173 if (block_node->data.block.name != nullptr) { 3174 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 3175 ir_mark_gen(ir_build_br(irb, parent_scope, block_node, scope_block->end_block, scope_block->is_comptime)); 3176 ir_set_cursor_at_end_and_append_block(irb, scope_block->end_block); 3177 return ir_build_phi(irb, parent_scope, block_node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 3178 } else { 3179 ir_gen_defers_for_block(irb, child_scope, outer_block_scope, false); 3180 return ir_mark_gen(ir_mark_gen(ir_build_const_void(irb, child_scope, block_node))); 3181 } 3182 } 3183 3184 static IrInstruction *ir_gen_bin_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 3185 IrInstruction *op1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 3186 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3187 3188 if (op1 == irb->codegen->invalid_instruction || op2 == irb->codegen->invalid_instruction) 3189 return irb->codegen->invalid_instruction; 3190 3191 return ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 3192 } 3193 3194 static IrInstruction *ir_gen_assign(IrBuilder *irb, Scope *scope, AstNode *node) { 3195 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); 3196 IrInstruction *rvalue = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3197 3198 if (lvalue == irb->codegen->invalid_instruction || rvalue == irb->codegen->invalid_instruction) 3199 return irb->codegen->invalid_instruction; 3200 3201 ir_build_store_ptr(irb, scope, node, lvalue, rvalue); 3202 return ir_build_const_void(irb, scope, node); 3203 } 3204 3205 static IrInstruction *ir_gen_assign_op(IrBuilder *irb, Scope *scope, AstNode *node, IrBinOp op_id) { 3206 IrInstruction *lvalue = ir_gen_node_extra(irb, node->data.bin_op_expr.op1, scope, LValPtr); 3207 if (lvalue == irb->codegen->invalid_instruction) 3208 return lvalue; 3209 IrInstruction *op1 = ir_build_load_ptr(irb, scope, node->data.bin_op_expr.op1, lvalue); 3210 IrInstruction *op2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3211 if (op2 == irb->codegen->invalid_instruction) 3212 return op2; 3213 IrInstruction *result = ir_build_bin_op(irb, scope, node, op_id, op1, op2, true); 3214 ir_build_store_ptr(irb, scope, node, lvalue, result); 3215 return ir_build_const_void(irb, scope, node); 3216 } 3217 3218 static IrInstruction *ir_gen_bool_or(IrBuilder *irb, Scope *scope, AstNode *node) { 3219 assert(node->type == NodeTypeBinOpExpr); 3220 3221 IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 3222 if (val1 == irb->codegen->invalid_instruction) 3223 return irb->codegen->invalid_instruction; 3224 IrBasicBlock *post_val1_block = irb->current_basic_block; 3225 3226 IrInstruction *is_comptime; 3227 if (ir_should_inline(irb->exec, scope)) { 3228 is_comptime = ir_build_const_bool(irb, scope, node, true); 3229 } else { 3230 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 3231 } 3232 3233 // block for when val1 == false 3234 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolOrFalse"); 3235 // block for when val1 == true (don't even evaluate the second part) 3236 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolOrTrue"); 3237 3238 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 3239 3240 ir_set_cursor_at_end_and_append_block(irb, false_block); 3241 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3242 if (val2 == irb->codegen->invalid_instruction) 3243 return irb->codegen->invalid_instruction; 3244 IrBasicBlock *post_val2_block = irb->current_basic_block; 3245 3246 ir_build_br(irb, scope, node, true_block, is_comptime); 3247 3248 ir_set_cursor_at_end_and_append_block(irb, true_block); 3249 3250 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 3251 incoming_values[0] = val1; 3252 incoming_values[1] = val2; 3253 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 3254 incoming_blocks[0] = post_val1_block; 3255 incoming_blocks[1] = post_val2_block; 3256 3257 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 3258 } 3259 3260 static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *node) { 3261 assert(node->type == NodeTypeBinOpExpr); 3262 3263 IrInstruction *val1 = ir_gen_node(irb, node->data.bin_op_expr.op1, scope); 3264 if (val1 == irb->codegen->invalid_instruction) 3265 return irb->codegen->invalid_instruction; 3266 IrBasicBlock *post_val1_block = irb->current_basic_block; 3267 3268 IrInstruction *is_comptime; 3269 if (ir_should_inline(irb->exec, scope)) { 3270 is_comptime = ir_build_const_bool(irb, scope, node, true); 3271 } else { 3272 is_comptime = ir_build_test_comptime(irb, scope, node, val1); 3273 } 3274 3275 // block for when val1 == true 3276 IrBasicBlock *true_block = ir_create_basic_block(irb, scope, "BoolAndTrue"); 3277 // block for when val1 == false (don't even evaluate the second part) 3278 IrBasicBlock *false_block = ir_create_basic_block(irb, scope, "BoolAndFalse"); 3279 3280 ir_build_cond_br(irb, scope, node, val1, true_block, false_block, is_comptime); 3281 3282 ir_set_cursor_at_end_and_append_block(irb, true_block); 3283 IrInstruction *val2 = ir_gen_node(irb, node->data.bin_op_expr.op2, scope); 3284 if (val2 == irb->codegen->invalid_instruction) 3285 return irb->codegen->invalid_instruction; 3286 IrBasicBlock *post_val2_block = irb->current_basic_block; 3287 3288 ir_build_br(irb, scope, node, false_block, is_comptime); 3289 3290 ir_set_cursor_at_end_and_append_block(irb, false_block); 3291 3292 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 3293 incoming_values[0] = val1; 3294 incoming_values[1] = val2; 3295 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 3296 incoming_blocks[0] = post_val1_block; 3297 incoming_blocks[1] = post_val2_block; 3298 3299 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 3300 } 3301 3302 static IrInstruction *ir_gen_maybe_ok_or(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 3303 assert(node->type == NodeTypeBinOpExpr); 3304 3305 AstNode *op1_node = node->data.bin_op_expr.op1; 3306 AstNode *op2_node = node->data.bin_op_expr.op2; 3307 3308 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); 3309 if (maybe_ptr == irb->codegen->invalid_instruction) 3310 return irb->codegen->invalid_instruction; 3311 3312 IrInstruction *maybe_val = ir_build_load_ptr(irb, parent_scope, node, maybe_ptr); 3313 IrInstruction *is_non_null = ir_build_test_nonnull(irb, parent_scope, node, maybe_val); 3314 3315 IrInstruction *is_comptime; 3316 if (ir_should_inline(irb->exec, parent_scope)) { 3317 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 3318 } else { 3319 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_non_null); 3320 } 3321 3322 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); 3323 IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); 3324 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); 3325 ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); 3326 3327 ir_set_cursor_at_end_and_append_block(irb, null_block); 3328 IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope); 3329 if (null_result == irb->codegen->invalid_instruction) 3330 return irb->codegen->invalid_instruction; 3331 IrBasicBlock *after_null_block = irb->current_basic_block; 3332 if (!instr_is_unreachable(null_result)) 3333 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 3334 3335 ir_set_cursor_at_end_and_append_block(irb, ok_block); 3336 IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, parent_scope, node, maybe_ptr, false); 3337 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 3338 IrBasicBlock *after_ok_block = irb->current_basic_block; 3339 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 3340 3341 ir_set_cursor_at_end_and_append_block(irb, end_block); 3342 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 3343 incoming_values[0] = null_result; 3344 incoming_values[1] = unwrapped_payload; 3345 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 3346 incoming_blocks[0] = after_null_block; 3347 incoming_blocks[1] = after_ok_block; 3348 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); 3349 } 3350 3351 static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 3352 assert(node->type == NodeTypeBinOpExpr); 3353 3354 AstNode *op1_node = node->data.bin_op_expr.op1; 3355 AstNode *op2_node = node->data.bin_op_expr.op2; 3356 3357 IrInstruction *err_set = ir_gen_node(irb, op1_node, parent_scope); 3358 if (err_set == irb->codegen->invalid_instruction) 3359 return irb->codegen->invalid_instruction; 3360 3361 IrInstruction *payload = ir_gen_node(irb, op2_node, parent_scope); 3362 if (payload == irb->codegen->invalid_instruction) 3363 return irb->codegen->invalid_instruction; 3364 3365 return ir_build_error_union(irb, parent_scope, node, err_set, payload); 3366 } 3367 3368 static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) { 3369 assert(node->type == NodeTypeBinOpExpr); 3370 3371 BinOpType bin_op_type = node->data.bin_op_expr.bin_op; 3372 switch (bin_op_type) { 3373 case BinOpTypeInvalid: 3374 zig_unreachable(); 3375 case BinOpTypeAssign: 3376 return ir_gen_assign(irb, scope, node); 3377 case BinOpTypeAssignTimes: 3378 return ir_gen_assign_op(irb, scope, node, IrBinOpMult); 3379 case BinOpTypeAssignTimesWrap: 3380 return ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap); 3381 case BinOpTypeAssignDiv: 3382 return ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified); 3383 case BinOpTypeAssignMod: 3384 return ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified); 3385 case BinOpTypeAssignPlus: 3386 return ir_gen_assign_op(irb, scope, node, IrBinOpAdd); 3387 case BinOpTypeAssignPlusWrap: 3388 return ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap); 3389 case BinOpTypeAssignMinus: 3390 return ir_gen_assign_op(irb, scope, node, IrBinOpSub); 3391 case BinOpTypeAssignMinusWrap: 3392 return ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap); 3393 case BinOpTypeAssignBitShiftLeft: 3394 return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy); 3395 case BinOpTypeAssignBitShiftRight: 3396 return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy); 3397 case BinOpTypeAssignBitAnd: 3398 return ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd); 3399 case BinOpTypeAssignBitXor: 3400 return ir_gen_assign_op(irb, scope, node, IrBinOpBinXor); 3401 case BinOpTypeAssignBitOr: 3402 return ir_gen_assign_op(irb, scope, node, IrBinOpBinOr); 3403 case BinOpTypeAssignMergeErrorSets: 3404 return ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets); 3405 case BinOpTypeBoolOr: 3406 return ir_gen_bool_or(irb, scope, node); 3407 case BinOpTypeBoolAnd: 3408 return ir_gen_bool_and(irb, scope, node); 3409 case BinOpTypeCmpEq: 3410 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq); 3411 case BinOpTypeCmpNotEq: 3412 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq); 3413 case BinOpTypeCmpLessThan: 3414 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan); 3415 case BinOpTypeCmpGreaterThan: 3416 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan); 3417 case BinOpTypeCmpLessOrEq: 3418 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq); 3419 case BinOpTypeCmpGreaterOrEq: 3420 return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq); 3421 case BinOpTypeBinOr: 3422 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr); 3423 case BinOpTypeBinXor: 3424 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor); 3425 case BinOpTypeBinAnd: 3426 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd); 3427 case BinOpTypeBitShiftLeft: 3428 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy); 3429 case BinOpTypeBitShiftRight: 3430 return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy); 3431 case BinOpTypeAdd: 3432 return ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd); 3433 case BinOpTypeAddWrap: 3434 return ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap); 3435 case BinOpTypeSub: 3436 return ir_gen_bin_op_id(irb, scope, node, IrBinOpSub); 3437 case BinOpTypeSubWrap: 3438 return ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap); 3439 case BinOpTypeMult: 3440 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMult); 3441 case BinOpTypeMultWrap: 3442 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap); 3443 case BinOpTypeDiv: 3444 return ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified); 3445 case BinOpTypeMod: 3446 return ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified); 3447 case BinOpTypeArrayCat: 3448 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat); 3449 case BinOpTypeArrayMult: 3450 return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult); 3451 case BinOpTypeMergeErrorSets: 3452 return ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets); 3453 case BinOpTypeUnwrapOptional: 3454 return ir_gen_maybe_ok_or(irb, scope, node); 3455 case BinOpTypeErrorUnion: 3456 return ir_gen_error_union(irb, scope, node); 3457 } 3458 zig_unreachable(); 3459 } 3460 3461 static IrInstruction *ir_gen_int_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 3462 assert(node->type == NodeTypeIntLiteral); 3463 3464 return ir_build_const_bigint(irb, scope, node, node->data.int_literal.bigint); 3465 } 3466 3467 static IrInstruction *ir_gen_float_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 3468 assert(node->type == NodeTypeFloatLiteral); 3469 3470 if (node->data.float_literal.overflow) { 3471 add_node_error(irb->codegen, node, buf_sprintf("float literal out of range of any type")); 3472 return irb->codegen->invalid_instruction; 3473 } 3474 3475 return ir_build_const_bigfloat(irb, scope, node, node->data.float_literal.bigfloat); 3476 } 3477 3478 static IrInstruction *ir_gen_char_lit(IrBuilder *irb, Scope *scope, AstNode *node) { 3479 assert(node->type == NodeTypeCharLiteral); 3480 3481 return ir_build_const_uint(irb, scope, node, node->data.char_literal.value); 3482 } 3483 3484 static IrInstruction *ir_gen_null_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 3485 assert(node->type == NodeTypeNullLiteral); 3486 3487 return ir_build_const_null(irb, scope, node); 3488 } 3489 3490 static IrInstruction *ir_gen_symbol(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 3491 Error err; 3492 assert(node->type == NodeTypeSymbol); 3493 3494 Buf *variable_name = node->data.symbol_expr.symbol; 3495 3496 if (buf_eql_str(variable_name, "_") && lval == LValPtr) { 3497 IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, node); 3498 const_instruction->base.value.type = get_pointer_to_type(irb->codegen, 3499 irb->codegen->builtin_types.entry_void, false); 3500 const_instruction->base.value.special = ConstValSpecialStatic; 3501 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialDiscard; 3502 return &const_instruction->base; 3503 } 3504 3505 ZigType *primitive_type; 3506 if ((err = get_primitive_type(irb->codegen, variable_name, &primitive_type))) { 3507 if (err == ErrorOverflow) { 3508 add_node_error(irb->codegen, node, 3509 buf_sprintf("primitive integer type '%s' exceeds maximum bit width of 65535", 3510 buf_ptr(variable_name))); 3511 return irb->codegen->invalid_instruction; 3512 } 3513 } else { 3514 IrInstruction *value = ir_build_const_type(irb, scope, node, primitive_type); 3515 if (lval == LValPtr) { 3516 return ir_build_ref(irb, scope, node, value, false, false); 3517 } else { 3518 return value; 3519 } 3520 } 3521 3522 ScopeFnDef *crossed_fndef_scope; 3523 ZigVar *var = find_variable(irb->codegen, scope, variable_name, &crossed_fndef_scope); 3524 if (var) { 3525 IrInstruction *var_ptr = ir_build_var_ptr_x(irb, scope, node, var, crossed_fndef_scope); 3526 if (lval == LValPtr) 3527 return var_ptr; 3528 else 3529 return ir_build_load_ptr(irb, scope, node, var_ptr); 3530 } 3531 3532 Tld *tld = find_decl(irb->codegen, scope, variable_name); 3533 if (tld) 3534 return ir_build_decl_ref(irb, scope, node, tld, lval); 3535 3536 if (node->owner->any_imports_failed) { 3537 // skip the error message since we had a failing import in this file 3538 // if an import breaks we don't need redundant undeclared identifier errors 3539 return irb->codegen->invalid_instruction; 3540 } 3541 3542 // TODO put a variable of same name with invalid type in global scope 3543 // so that future references to this same name will find a variable with an invalid type 3544 add_node_error(irb->codegen, node, buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); 3545 return irb->codegen->invalid_instruction; 3546 } 3547 3548 static IrInstruction *ir_gen_array_access(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 3549 assert(node->type == NodeTypeArrayAccessExpr); 3550 3551 AstNode *array_ref_node = node->data.array_access_expr.array_ref_expr; 3552 IrInstruction *array_ref_instruction = ir_gen_node_extra(irb, array_ref_node, scope, LValPtr); 3553 if (array_ref_instruction == irb->codegen->invalid_instruction) 3554 return array_ref_instruction; 3555 3556 AstNode *subscript_node = node->data.array_access_expr.subscript; 3557 IrInstruction *subscript_instruction = ir_gen_node(irb, subscript_node, scope); 3558 if (subscript_instruction == irb->codegen->invalid_instruction) 3559 return subscript_instruction; 3560 3561 IrInstruction *ptr_instruction = ir_build_elem_ptr(irb, scope, node, array_ref_instruction, 3562 subscript_instruction, true, PtrLenSingle); 3563 if (lval == LValPtr) 3564 return ptr_instruction; 3565 3566 return ir_build_load_ptr(irb, scope, node, ptr_instruction); 3567 } 3568 3569 static IrInstruction *ir_gen_field_access(IrBuilder *irb, Scope *scope, AstNode *node) { 3570 assert(node->type == NodeTypeFieldAccessExpr); 3571 3572 AstNode *container_ref_node = node->data.field_access_expr.struct_expr; 3573 Buf *field_name = node->data.field_access_expr.field_name; 3574 3575 IrInstruction *container_ref_instruction = ir_gen_node_extra(irb, container_ref_node, scope, LValPtr); 3576 if (container_ref_instruction == irb->codegen->invalid_instruction) 3577 return container_ref_instruction; 3578 3579 return ir_build_field_ptr(irb, scope, node, container_ref_instruction, field_name); 3580 } 3581 3582 static IrInstruction *ir_gen_overflow_op(IrBuilder *irb, Scope *scope, AstNode *node, IrOverflowOp op) { 3583 assert(node->type == NodeTypeFnCallExpr); 3584 3585 AstNode *type_node = node->data.fn_call_expr.params.at(0); 3586 AstNode *op1_node = node->data.fn_call_expr.params.at(1); 3587 AstNode *op2_node = node->data.fn_call_expr.params.at(2); 3588 AstNode *result_ptr_node = node->data.fn_call_expr.params.at(3); 3589 3590 3591 IrInstruction *type_value = ir_gen_node(irb, type_node, scope); 3592 if (type_value == irb->codegen->invalid_instruction) 3593 return irb->codegen->invalid_instruction; 3594 3595 IrInstruction *op1 = ir_gen_node(irb, op1_node, scope); 3596 if (op1 == irb->codegen->invalid_instruction) 3597 return irb->codegen->invalid_instruction; 3598 3599 IrInstruction *op2 = ir_gen_node(irb, op2_node, scope); 3600 if (op2 == irb->codegen->invalid_instruction) 3601 return irb->codegen->invalid_instruction; 3602 3603 IrInstruction *result_ptr = ir_gen_node(irb, result_ptr_node, scope); 3604 if (result_ptr == irb->codegen->invalid_instruction) 3605 return irb->codegen->invalid_instruction; 3606 3607 return ir_build_overflow_op(irb, scope, node, op, type_value, op1, op2, result_ptr, nullptr); 3608 } 3609 3610 static IrInstruction *ir_gen_this(IrBuilder *irb, Scope *orig_scope, AstNode *node) { 3611 for (Scope *it_scope = orig_scope; it_scope != nullptr; it_scope = it_scope->parent) { 3612 if (it_scope->id == ScopeIdDecls) { 3613 ScopeDecls *decls_scope = (ScopeDecls *)it_scope; 3614 ZigType *container_type = decls_scope->container_type; 3615 if (container_type != nullptr) { 3616 return ir_build_const_type(irb, orig_scope, node, container_type); 3617 } else { 3618 return ir_build_const_import(irb, orig_scope, node, decls_scope->import); 3619 } 3620 } 3621 } 3622 zig_unreachable(); 3623 } 3624 3625 static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 3626 assert(node->type == NodeTypeFnCallExpr); 3627 3628 AstNode *fn_ref_expr = node->data.fn_call_expr.fn_ref_expr; 3629 Buf *name = fn_ref_expr->data.symbol_expr.symbol; 3630 auto entry = irb->codegen->builtin_fn_table.maybe_get(name); 3631 3632 if (!entry) { 3633 add_node_error(irb->codegen, node, 3634 buf_sprintf("invalid builtin function: '%s'", buf_ptr(name))); 3635 return irb->codegen->invalid_instruction; 3636 } 3637 3638 BuiltinFnEntry *builtin_fn = entry->value; 3639 size_t actual_param_count = node->data.fn_call_expr.params.length; 3640 3641 if (builtin_fn->param_count != SIZE_MAX && builtin_fn->param_count != actual_param_count) { 3642 add_node_error(irb->codegen, node, 3643 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize, 3644 builtin_fn->param_count, actual_param_count)); 3645 return irb->codegen->invalid_instruction; 3646 } 3647 3648 bool is_async = exec_is_async(irb->exec); 3649 3650 switch (builtin_fn->id) { 3651 case BuiltinFnIdInvalid: 3652 zig_unreachable(); 3653 case BuiltinFnIdTypeof: 3654 { 3655 AstNode *arg_node = node->data.fn_call_expr.params.at(0); 3656 IrInstruction *arg = ir_gen_node(irb, arg_node, scope); 3657 if (arg == irb->codegen->invalid_instruction) 3658 return arg; 3659 3660 IrInstruction *type_of = ir_build_typeof(irb, scope, node, arg); 3661 return ir_lval_wrap(irb, scope, type_of, lval); 3662 } 3663 case BuiltinFnIdSetCold: 3664 { 3665 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3666 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3667 if (arg0_value == irb->codegen->invalid_instruction) 3668 return arg0_value; 3669 3670 IrInstruction *set_cold = ir_build_set_cold(irb, scope, node, arg0_value); 3671 return ir_lval_wrap(irb, scope, set_cold, lval); 3672 } 3673 case BuiltinFnIdSetRuntimeSafety: 3674 { 3675 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3676 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3677 if (arg0_value == irb->codegen->invalid_instruction) 3678 return arg0_value; 3679 3680 IrInstruction *set_safety = ir_build_set_runtime_safety(irb, scope, node, arg0_value); 3681 return ir_lval_wrap(irb, scope, set_safety, lval); 3682 } 3683 case BuiltinFnIdSetFloatMode: 3684 { 3685 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3686 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3687 if (arg0_value == irb->codegen->invalid_instruction) 3688 return arg0_value; 3689 3690 IrInstruction *set_float_mode = ir_build_set_float_mode(irb, scope, node, arg0_value); 3691 return ir_lval_wrap(irb, scope, set_float_mode, lval); 3692 } 3693 case BuiltinFnIdSizeof: 3694 { 3695 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3696 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3697 if (arg0_value == irb->codegen->invalid_instruction) 3698 return arg0_value; 3699 3700 IrInstruction *size_of = ir_build_size_of(irb, scope, node, arg0_value); 3701 return ir_lval_wrap(irb, scope, size_of, lval); 3702 } 3703 case BuiltinFnIdCtz: 3704 { 3705 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3706 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3707 if (arg0_value == irb->codegen->invalid_instruction) 3708 return arg0_value; 3709 3710 IrInstruction *ctz = ir_build_ctz(irb, scope, node, arg0_value); 3711 return ir_lval_wrap(irb, scope, ctz, lval); 3712 } 3713 case BuiltinFnIdPopCount: 3714 { 3715 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3716 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3717 if (arg0_value == irb->codegen->invalid_instruction) 3718 return arg0_value; 3719 3720 IrInstruction *instr = ir_build_pop_count(irb, scope, node, arg0_value); 3721 return ir_lval_wrap(irb, scope, instr, lval); 3722 } 3723 case BuiltinFnIdClz: 3724 { 3725 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3726 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3727 if (arg0_value == irb->codegen->invalid_instruction) 3728 return arg0_value; 3729 3730 IrInstruction *clz = ir_build_clz(irb, scope, node, arg0_value); 3731 return ir_lval_wrap(irb, scope, clz, lval); 3732 } 3733 case BuiltinFnIdImport: 3734 { 3735 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3736 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3737 if (arg0_value == irb->codegen->invalid_instruction) 3738 return arg0_value; 3739 3740 IrInstruction *import = ir_build_import(irb, scope, node, arg0_value); 3741 return ir_lval_wrap(irb, scope, import, lval); 3742 } 3743 case BuiltinFnIdCImport: 3744 { 3745 IrInstruction *c_import = ir_build_c_import(irb, scope, node); 3746 return ir_lval_wrap(irb, scope, c_import, lval); 3747 } 3748 case BuiltinFnIdCInclude: 3749 { 3750 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3751 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3752 if (arg0_value == irb->codegen->invalid_instruction) 3753 return arg0_value; 3754 3755 if (!exec_c_import_buf(irb->exec)) { 3756 add_node_error(irb->codegen, node, buf_sprintf("C include valid only inside C import block")); 3757 return irb->codegen->invalid_instruction; 3758 } 3759 3760 IrInstruction *c_include = ir_build_c_include(irb, scope, node, arg0_value); 3761 return ir_lval_wrap(irb, scope, c_include, lval); 3762 } 3763 case BuiltinFnIdCDefine: 3764 { 3765 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3766 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3767 if (arg0_value == irb->codegen->invalid_instruction) 3768 return arg0_value; 3769 3770 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 3771 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 3772 if (arg1_value == irb->codegen->invalid_instruction) 3773 return arg1_value; 3774 3775 if (!exec_c_import_buf(irb->exec)) { 3776 add_node_error(irb->codegen, node, buf_sprintf("C define valid only inside C import block")); 3777 return irb->codegen->invalid_instruction; 3778 } 3779 3780 IrInstruction *c_define = ir_build_c_define(irb, scope, node, arg0_value, arg1_value); 3781 return ir_lval_wrap(irb, scope, c_define, lval); 3782 } 3783 case BuiltinFnIdCUndef: 3784 { 3785 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3786 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3787 if (arg0_value == irb->codegen->invalid_instruction) 3788 return arg0_value; 3789 3790 if (!exec_c_import_buf(irb->exec)) { 3791 add_node_error(irb->codegen, node, buf_sprintf("C undef valid only inside C import block")); 3792 return irb->codegen->invalid_instruction; 3793 } 3794 3795 IrInstruction *c_undef = ir_build_c_undef(irb, scope, node, arg0_value); 3796 return ir_lval_wrap(irb, scope, c_undef, lval); 3797 } 3798 case BuiltinFnIdCompileErr: 3799 { 3800 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3801 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3802 if (arg0_value == irb->codegen->invalid_instruction) 3803 return arg0_value; 3804 3805 IrInstruction *compile_err = ir_build_compile_err(irb, scope, node, arg0_value); 3806 return ir_lval_wrap(irb, scope, compile_err, lval); 3807 } 3808 case BuiltinFnIdCompileLog: 3809 { 3810 IrInstruction **args = allocate<IrInstruction*>(actual_param_count); 3811 3812 for (size_t i = 0; i < actual_param_count; i += 1) { 3813 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 3814 args[i] = ir_gen_node(irb, arg_node, scope); 3815 if (args[i] == irb->codegen->invalid_instruction) 3816 return irb->codegen->invalid_instruction; 3817 } 3818 3819 IrInstruction *compile_log = ir_build_compile_log(irb, scope, node, actual_param_count, args); 3820 return ir_lval_wrap(irb, scope, compile_log, lval); 3821 } 3822 case BuiltinFnIdErrName: 3823 { 3824 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3825 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3826 if (arg0_value == irb->codegen->invalid_instruction) 3827 return arg0_value; 3828 3829 IrInstruction *err_name = ir_build_err_name(irb, scope, node, arg0_value); 3830 return ir_lval_wrap(irb, scope, err_name, lval); 3831 } 3832 case BuiltinFnIdEmbedFile: 3833 { 3834 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3835 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3836 if (arg0_value == irb->codegen->invalid_instruction) 3837 return arg0_value; 3838 3839 IrInstruction *embed_file = ir_build_embed_file(irb, scope, node, arg0_value); 3840 return ir_lval_wrap(irb, scope, embed_file, lval); 3841 } 3842 case BuiltinFnIdCmpxchgWeak: 3843 case BuiltinFnIdCmpxchgStrong: 3844 { 3845 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3846 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3847 if (arg0_value == irb->codegen->invalid_instruction) 3848 return arg0_value; 3849 3850 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 3851 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 3852 if (arg1_value == irb->codegen->invalid_instruction) 3853 return arg1_value; 3854 3855 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 3856 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 3857 if (arg2_value == irb->codegen->invalid_instruction) 3858 return arg2_value; 3859 3860 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 3861 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 3862 if (arg3_value == irb->codegen->invalid_instruction) 3863 return arg3_value; 3864 3865 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 3866 IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); 3867 if (arg4_value == irb->codegen->invalid_instruction) 3868 return arg4_value; 3869 3870 AstNode *arg5_node = node->data.fn_call_expr.params.at(5); 3871 IrInstruction *arg5_value = ir_gen_node(irb, arg5_node, scope); 3872 if (arg5_value == irb->codegen->invalid_instruction) 3873 return arg5_value; 3874 3875 IrInstruction *cmpxchg = ir_build_cmpxchg(irb, scope, node, arg0_value, arg1_value, 3876 arg2_value, arg3_value, arg4_value, arg5_value, (builtin_fn->id == BuiltinFnIdCmpxchgWeak), 3877 nullptr, AtomicOrderUnordered, AtomicOrderUnordered); 3878 return ir_lval_wrap(irb, scope, cmpxchg, lval); 3879 } 3880 case BuiltinFnIdFence: 3881 { 3882 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3883 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3884 if (arg0_value == irb->codegen->invalid_instruction) 3885 return arg0_value; 3886 3887 IrInstruction *fence = ir_build_fence(irb, scope, node, arg0_value, AtomicOrderUnordered); 3888 return ir_lval_wrap(irb, scope, fence, lval); 3889 } 3890 case BuiltinFnIdDivExact: 3891 { 3892 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3893 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3894 if (arg0_value == irb->codegen->invalid_instruction) 3895 return arg0_value; 3896 3897 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 3898 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 3899 if (arg1_value == irb->codegen->invalid_instruction) 3900 return arg1_value; 3901 3902 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivExact, arg0_value, arg1_value, true); 3903 return ir_lval_wrap(irb, scope, bin_op, lval); 3904 } 3905 case BuiltinFnIdDivTrunc: 3906 { 3907 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3908 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3909 if (arg0_value == irb->codegen->invalid_instruction) 3910 return arg0_value; 3911 3912 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 3913 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 3914 if (arg1_value == irb->codegen->invalid_instruction) 3915 return arg1_value; 3916 3917 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivTrunc, arg0_value, arg1_value, true); 3918 return ir_lval_wrap(irb, scope, bin_op, lval); 3919 } 3920 case BuiltinFnIdDivFloor: 3921 { 3922 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3923 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3924 if (arg0_value == irb->codegen->invalid_instruction) 3925 return arg0_value; 3926 3927 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 3928 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 3929 if (arg1_value == irb->codegen->invalid_instruction) 3930 return arg1_value; 3931 3932 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpDivFloor, arg0_value, arg1_value, true); 3933 return ir_lval_wrap(irb, scope, bin_op, lval); 3934 } 3935 case BuiltinFnIdRem: 3936 { 3937 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3938 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3939 if (arg0_value == irb->codegen->invalid_instruction) 3940 return arg0_value; 3941 3942 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 3943 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 3944 if (arg1_value == irb->codegen->invalid_instruction) 3945 return arg1_value; 3946 3947 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemRem, arg0_value, arg1_value, true); 3948 return ir_lval_wrap(irb, scope, bin_op, lval); 3949 } 3950 case BuiltinFnIdMod: 3951 { 3952 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3953 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3954 if (arg0_value == irb->codegen->invalid_instruction) 3955 return arg0_value; 3956 3957 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 3958 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 3959 if (arg1_value == irb->codegen->invalid_instruction) 3960 return arg1_value; 3961 3962 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpRemMod, arg0_value, arg1_value, true); 3963 return ir_lval_wrap(irb, scope, bin_op, lval); 3964 } 3965 case BuiltinFnIdSqrt: 3966 { 3967 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3968 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3969 if (arg0_value == irb->codegen->invalid_instruction) 3970 return arg0_value; 3971 3972 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 3973 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 3974 if (arg1_value == irb->codegen->invalid_instruction) 3975 return arg1_value; 3976 3977 IrInstruction *ir_sqrt = ir_build_sqrt(irb, scope, node, arg0_value, arg1_value); 3978 return ir_lval_wrap(irb, scope, ir_sqrt, lval); 3979 } 3980 case BuiltinFnIdTruncate: 3981 { 3982 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3983 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3984 if (arg0_value == irb->codegen->invalid_instruction) 3985 return arg0_value; 3986 3987 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 3988 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 3989 if (arg1_value == irb->codegen->invalid_instruction) 3990 return arg1_value; 3991 3992 IrInstruction *truncate = ir_build_truncate(irb, scope, node, arg0_value, arg1_value); 3993 return ir_lval_wrap(irb, scope, truncate, lval); 3994 } 3995 case BuiltinFnIdIntCast: 3996 { 3997 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 3998 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 3999 if (arg0_value == irb->codegen->invalid_instruction) 4000 return arg0_value; 4001 4002 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4003 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4004 if (arg1_value == irb->codegen->invalid_instruction) 4005 return arg1_value; 4006 4007 IrInstruction *result = ir_build_int_cast(irb, scope, node, arg0_value, arg1_value); 4008 return ir_lval_wrap(irb, scope, result, lval); 4009 } 4010 case BuiltinFnIdFloatCast: 4011 { 4012 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4013 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4014 if (arg0_value == irb->codegen->invalid_instruction) 4015 return arg0_value; 4016 4017 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4018 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4019 if (arg1_value == irb->codegen->invalid_instruction) 4020 return arg1_value; 4021 4022 IrInstruction *result = ir_build_float_cast(irb, scope, node, arg0_value, arg1_value); 4023 return ir_lval_wrap(irb, scope, result, lval); 4024 } 4025 case BuiltinFnIdErrSetCast: 4026 { 4027 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4028 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4029 if (arg0_value == irb->codegen->invalid_instruction) 4030 return arg0_value; 4031 4032 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4033 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4034 if (arg1_value == irb->codegen->invalid_instruction) 4035 return arg1_value; 4036 4037 IrInstruction *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value); 4038 return ir_lval_wrap(irb, scope, result, lval); 4039 } 4040 case BuiltinFnIdFromBytes: 4041 { 4042 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4043 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4044 if (arg0_value == irb->codegen->invalid_instruction) 4045 return arg0_value; 4046 4047 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4048 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4049 if (arg1_value == irb->codegen->invalid_instruction) 4050 return arg1_value; 4051 4052 IrInstruction *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value); 4053 return ir_lval_wrap(irb, scope, result, lval); 4054 } 4055 case BuiltinFnIdToBytes: 4056 { 4057 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4058 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4059 if (arg0_value == irb->codegen->invalid_instruction) 4060 return arg0_value; 4061 4062 IrInstruction *result = ir_build_to_bytes(irb, scope, node, arg0_value); 4063 return ir_lval_wrap(irb, scope, result, lval); 4064 } 4065 case BuiltinFnIdIntToFloat: 4066 { 4067 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4068 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4069 if (arg0_value == irb->codegen->invalid_instruction) 4070 return arg0_value; 4071 4072 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4073 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4074 if (arg1_value == irb->codegen->invalid_instruction) 4075 return arg1_value; 4076 4077 IrInstruction *result = ir_build_int_to_float(irb, scope, node, arg0_value, arg1_value); 4078 return ir_lval_wrap(irb, scope, result, lval); 4079 } 4080 case BuiltinFnIdFloatToInt: 4081 { 4082 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4083 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4084 if (arg0_value == irb->codegen->invalid_instruction) 4085 return arg0_value; 4086 4087 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4088 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4089 if (arg1_value == irb->codegen->invalid_instruction) 4090 return arg1_value; 4091 4092 IrInstruction *result = ir_build_float_to_int(irb, scope, node, arg0_value, arg1_value); 4093 return ir_lval_wrap(irb, scope, result, lval); 4094 } 4095 case BuiltinFnIdErrToInt: 4096 { 4097 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4098 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4099 if (arg0_value == irb->codegen->invalid_instruction) 4100 return arg0_value; 4101 4102 IrInstruction *result = ir_build_err_to_int(irb, scope, node, arg0_value); 4103 return ir_lval_wrap(irb, scope, result, lval); 4104 } 4105 case BuiltinFnIdIntToErr: 4106 { 4107 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4108 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4109 if (arg0_value == irb->codegen->invalid_instruction) 4110 return arg0_value; 4111 4112 IrInstruction *result = ir_build_int_to_err(irb, scope, node, arg0_value); 4113 return ir_lval_wrap(irb, scope, result, lval); 4114 } 4115 case BuiltinFnIdBoolToInt: 4116 { 4117 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4118 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4119 if (arg0_value == irb->codegen->invalid_instruction) 4120 return arg0_value; 4121 4122 IrInstruction *result = ir_build_bool_to_int(irb, scope, node, arg0_value); 4123 return ir_lval_wrap(irb, scope, result, lval); 4124 } 4125 case BuiltinFnIdIntType: 4126 { 4127 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4128 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4129 if (arg0_value == irb->codegen->invalid_instruction) 4130 return arg0_value; 4131 4132 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4133 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4134 if (arg1_value == irb->codegen->invalid_instruction) 4135 return arg1_value; 4136 4137 IrInstruction *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value); 4138 return ir_lval_wrap(irb, scope, int_type, lval); 4139 } 4140 case BuiltinFnIdMemcpy: 4141 { 4142 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4143 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4144 if (arg0_value == irb->codegen->invalid_instruction) 4145 return arg0_value; 4146 4147 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4148 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4149 if (arg1_value == irb->codegen->invalid_instruction) 4150 return arg1_value; 4151 4152 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4153 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4154 if (arg2_value == irb->codegen->invalid_instruction) 4155 return arg2_value; 4156 4157 IrInstruction *ir_memcpy = ir_build_memcpy(irb, scope, node, arg0_value, arg1_value, arg2_value); 4158 return ir_lval_wrap(irb, scope, ir_memcpy, lval); 4159 } 4160 case BuiltinFnIdMemset: 4161 { 4162 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4163 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4164 if (arg0_value == irb->codegen->invalid_instruction) 4165 return arg0_value; 4166 4167 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4168 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4169 if (arg1_value == irb->codegen->invalid_instruction) 4170 return arg1_value; 4171 4172 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4173 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4174 if (arg2_value == irb->codegen->invalid_instruction) 4175 return arg2_value; 4176 4177 IrInstruction *ir_memset = ir_build_memset(irb, scope, node, arg0_value, arg1_value, arg2_value); 4178 return ir_lval_wrap(irb, scope, ir_memset, lval); 4179 } 4180 case BuiltinFnIdMemberCount: 4181 { 4182 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4183 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4184 if (arg0_value == irb->codegen->invalid_instruction) 4185 return arg0_value; 4186 4187 IrInstruction *member_count = ir_build_member_count(irb, scope, node, arg0_value); 4188 return ir_lval_wrap(irb, scope, member_count, lval); 4189 } 4190 case BuiltinFnIdMemberType: 4191 { 4192 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4193 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4194 if (arg0_value == irb->codegen->invalid_instruction) 4195 return arg0_value; 4196 4197 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4198 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4199 if (arg1_value == irb->codegen->invalid_instruction) 4200 return arg1_value; 4201 4202 4203 IrInstruction *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value); 4204 return ir_lval_wrap(irb, scope, member_type, lval); 4205 } 4206 case BuiltinFnIdMemberName: 4207 { 4208 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4209 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4210 if (arg0_value == irb->codegen->invalid_instruction) 4211 return arg0_value; 4212 4213 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4214 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4215 if (arg1_value == irb->codegen->invalid_instruction) 4216 return arg1_value; 4217 4218 4219 IrInstruction *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value); 4220 return ir_lval_wrap(irb, scope, member_name, lval); 4221 } 4222 case BuiltinFnIdField: 4223 { 4224 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4225 IrInstruction *arg0_value = ir_gen_node_extra(irb, arg0_node, scope, LValPtr); 4226 if (arg0_value == irb->codegen->invalid_instruction) 4227 return arg0_value; 4228 4229 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4230 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4231 if (arg1_value == irb->codegen->invalid_instruction) 4232 return arg1_value; 4233 4234 IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value); 4235 4236 if (lval == LValPtr) 4237 return ptr_instruction; 4238 4239 return ir_build_load_ptr(irb, scope, node, ptr_instruction); 4240 } 4241 case BuiltinFnIdTypeInfo: 4242 { 4243 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4244 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4245 if (arg0_value == irb->codegen->invalid_instruction) 4246 return arg0_value; 4247 4248 IrInstruction *type_info = ir_build_type_info(irb, scope, node, arg0_value); 4249 return ir_lval_wrap(irb, scope, type_info, lval); 4250 } 4251 case BuiltinFnIdBreakpoint: 4252 return ir_lval_wrap(irb, scope, ir_build_breakpoint(irb, scope, node), lval); 4253 case BuiltinFnIdReturnAddress: 4254 return ir_lval_wrap(irb, scope, ir_build_return_address(irb, scope, node), lval); 4255 case BuiltinFnIdFrameAddress: 4256 return ir_lval_wrap(irb, scope, ir_build_frame_address(irb, scope, node), lval); 4257 case BuiltinFnIdHandle: 4258 if (!irb->exec->fn_entry) { 4259 add_node_error(irb->codegen, node, buf_sprintf("@handle() called outside of function definition")); 4260 return irb->codegen->invalid_instruction; 4261 } 4262 if (!is_async) { 4263 add_node_error(irb->codegen, node, buf_sprintf("@handle() in non-async function")); 4264 return irb->codegen->invalid_instruction; 4265 } 4266 return ir_lval_wrap(irb, scope, ir_build_handle(irb, scope, node), lval); 4267 case BuiltinFnIdAlignOf: 4268 { 4269 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4270 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4271 if (arg0_value == irb->codegen->invalid_instruction) 4272 return arg0_value; 4273 4274 IrInstruction *align_of = ir_build_align_of(irb, scope, node, arg0_value); 4275 return ir_lval_wrap(irb, scope, align_of, lval); 4276 } 4277 case BuiltinFnIdAddWithOverflow: 4278 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpAdd), lval); 4279 case BuiltinFnIdSubWithOverflow: 4280 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpSub), lval); 4281 case BuiltinFnIdMulWithOverflow: 4282 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpMul), lval); 4283 case BuiltinFnIdShlWithOverflow: 4284 return ir_lval_wrap(irb, scope, ir_gen_overflow_op(irb, scope, node, IrOverflowOpShl), lval); 4285 case BuiltinFnIdTypeName: 4286 { 4287 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4288 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4289 if (arg0_value == irb->codegen->invalid_instruction) 4290 return arg0_value; 4291 4292 IrInstruction *type_name = ir_build_type_name(irb, scope, node, arg0_value); 4293 return ir_lval_wrap(irb, scope, type_name, lval); 4294 } 4295 case BuiltinFnIdPanic: 4296 { 4297 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4298 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4299 if (arg0_value == irb->codegen->invalid_instruction) 4300 return arg0_value; 4301 4302 IrInstruction *panic = ir_build_panic(irb, scope, node, arg0_value); 4303 return ir_lval_wrap(irb, scope, panic, lval); 4304 } 4305 case BuiltinFnIdPtrCast: 4306 { 4307 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4308 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4309 if (arg0_value == irb->codegen->invalid_instruction) 4310 return arg0_value; 4311 4312 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4313 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4314 if (arg1_value == irb->codegen->invalid_instruction) 4315 return arg1_value; 4316 4317 IrInstruction *ptr_cast = ir_build_ptr_cast(irb, scope, node, arg0_value, arg1_value); 4318 return ir_lval_wrap(irb, scope, ptr_cast, lval); 4319 } 4320 case BuiltinFnIdBitCast: 4321 { 4322 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4323 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4324 if (arg0_value == irb->codegen->invalid_instruction) 4325 return arg0_value; 4326 4327 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4328 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4329 if (arg1_value == irb->codegen->invalid_instruction) 4330 return arg1_value; 4331 4332 IrInstruction *bit_cast = ir_build_bit_cast(irb, scope, node, arg0_value, arg1_value); 4333 return ir_lval_wrap(irb, scope, bit_cast, lval); 4334 } 4335 case BuiltinFnIdIntToPtr: 4336 { 4337 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4338 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4339 if (arg0_value == irb->codegen->invalid_instruction) 4340 return arg0_value; 4341 4342 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4343 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4344 if (arg1_value == irb->codegen->invalid_instruction) 4345 return arg1_value; 4346 4347 IrInstruction *int_to_ptr = ir_build_int_to_ptr(irb, scope, node, arg0_value, arg1_value); 4348 return ir_lval_wrap(irb, scope, int_to_ptr, lval); 4349 } 4350 case BuiltinFnIdPtrToInt: 4351 { 4352 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4353 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4354 if (arg0_value == irb->codegen->invalid_instruction) 4355 return arg0_value; 4356 4357 IrInstruction *ptr_to_int = ir_build_ptr_to_int(irb, scope, node, arg0_value); 4358 return ir_lval_wrap(irb, scope, ptr_to_int, lval); 4359 } 4360 case BuiltinFnIdTagName: 4361 { 4362 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4363 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4364 if (arg0_value == irb->codegen->invalid_instruction) 4365 return arg0_value; 4366 4367 IrInstruction *actual_tag = ir_build_union_tag(irb, scope, node, arg0_value); 4368 IrInstruction *tag_name = ir_build_tag_name(irb, scope, node, actual_tag); 4369 return ir_lval_wrap(irb, scope, tag_name, lval); 4370 } 4371 case BuiltinFnIdTagType: 4372 { 4373 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4374 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4375 if (arg0_value == irb->codegen->invalid_instruction) 4376 return arg0_value; 4377 4378 IrInstruction *tag_type = ir_build_tag_type(irb, scope, node, arg0_value); 4379 return ir_lval_wrap(irb, scope, tag_type, lval); 4380 } 4381 case BuiltinFnIdFieldParentPtr: 4382 { 4383 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4384 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4385 if (arg0_value == irb->codegen->invalid_instruction) 4386 return arg0_value; 4387 4388 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4389 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4390 if (arg1_value == irb->codegen->invalid_instruction) 4391 return arg1_value; 4392 4393 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4394 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4395 if (arg2_value == irb->codegen->invalid_instruction) 4396 return arg2_value; 4397 4398 IrInstruction *field_parent_ptr = ir_build_field_parent_ptr(irb, scope, node, arg0_value, arg1_value, arg2_value, nullptr); 4399 return ir_lval_wrap(irb, scope, field_parent_ptr, lval); 4400 } 4401 case BuiltinFnIdByteOffsetOf: 4402 { 4403 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4404 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4405 if (arg0_value == irb->codegen->invalid_instruction) 4406 return arg0_value; 4407 4408 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4409 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4410 if (arg1_value == irb->codegen->invalid_instruction) 4411 return arg1_value; 4412 4413 IrInstruction *offset_of = ir_build_byte_offset_of(irb, scope, node, arg0_value, arg1_value); 4414 return ir_lval_wrap(irb, scope, offset_of, lval); 4415 } 4416 case BuiltinFnIdBitOffsetOf: 4417 { 4418 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4419 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4420 if (arg0_value == irb->codegen->invalid_instruction) 4421 return arg0_value; 4422 4423 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4424 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4425 if (arg1_value == irb->codegen->invalid_instruction) 4426 return arg1_value; 4427 4428 IrInstruction *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); 4429 return ir_lval_wrap(irb, scope, offset_of, lval); 4430 } 4431 case BuiltinFnIdInlineCall: 4432 case BuiltinFnIdNoInlineCall: 4433 { 4434 if (node->data.fn_call_expr.params.length == 0) { 4435 add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0")); 4436 return irb->codegen->invalid_instruction; 4437 } 4438 4439 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(0); 4440 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 4441 if (fn_ref == irb->codegen->invalid_instruction) 4442 return fn_ref; 4443 4444 size_t arg_count = node->data.fn_call_expr.params.length - 1; 4445 4446 IrInstruction **args = allocate<IrInstruction*>(arg_count); 4447 for (size_t i = 0; i < arg_count; i += 1) { 4448 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 1); 4449 args[i] = ir_gen_node(irb, arg_node, scope); 4450 if (args[i] == irb->codegen->invalid_instruction) 4451 return args[i]; 4452 } 4453 FnInline fn_inline = (builtin_fn->id == BuiltinFnIdInlineCall) ? FnInlineAlways : FnInlineNever; 4454 4455 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, fn_inline, false, nullptr, nullptr); 4456 return ir_lval_wrap(irb, scope, call, lval); 4457 } 4458 case BuiltinFnIdNewStackCall: 4459 { 4460 if (node->data.fn_call_expr.params.length == 0) { 4461 add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0")); 4462 return irb->codegen->invalid_instruction; 4463 } 4464 4465 AstNode *new_stack_node = node->data.fn_call_expr.params.at(0); 4466 IrInstruction *new_stack = ir_gen_node(irb, new_stack_node, scope); 4467 if (new_stack == irb->codegen->invalid_instruction) 4468 return new_stack; 4469 4470 AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); 4471 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 4472 if (fn_ref == irb->codegen->invalid_instruction) 4473 return fn_ref; 4474 4475 size_t arg_count = node->data.fn_call_expr.params.length - 2; 4476 4477 IrInstruction **args = allocate<IrInstruction*>(arg_count); 4478 for (size_t i = 0; i < arg_count; i += 1) { 4479 AstNode *arg_node = node->data.fn_call_expr.params.at(i + 2); 4480 args[i] = ir_gen_node(irb, arg_node, scope); 4481 if (args[i] == irb->codegen->invalid_instruction) 4482 return args[i]; 4483 } 4484 4485 IrInstruction *call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, false, nullptr, new_stack); 4486 return ir_lval_wrap(irb, scope, call, lval); 4487 } 4488 case BuiltinFnIdTypeId: 4489 { 4490 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4491 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4492 if (arg0_value == irb->codegen->invalid_instruction) 4493 return arg0_value; 4494 4495 IrInstruction *type_id = ir_build_type_id(irb, scope, node, arg0_value); 4496 return ir_lval_wrap(irb, scope, type_id, lval); 4497 } 4498 case BuiltinFnIdShlExact: 4499 { 4500 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4501 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4502 if (arg0_value == irb->codegen->invalid_instruction) 4503 return arg0_value; 4504 4505 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4506 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4507 if (arg1_value == irb->codegen->invalid_instruction) 4508 return arg1_value; 4509 4510 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftLeftExact, arg0_value, arg1_value, true); 4511 return ir_lval_wrap(irb, scope, bin_op, lval); 4512 } 4513 case BuiltinFnIdShrExact: 4514 { 4515 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4516 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4517 if (arg0_value == irb->codegen->invalid_instruction) 4518 return arg0_value; 4519 4520 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4521 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4522 if (arg1_value == irb->codegen->invalid_instruction) 4523 return arg1_value; 4524 4525 IrInstruction *bin_op = ir_build_bin_op(irb, scope, node, IrBinOpBitShiftRightExact, arg0_value, arg1_value, true); 4526 return ir_lval_wrap(irb, scope, bin_op, lval); 4527 } 4528 case BuiltinFnIdSetEvalBranchQuota: 4529 { 4530 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4531 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4532 if (arg0_value == irb->codegen->invalid_instruction) 4533 return arg0_value; 4534 4535 IrInstruction *set_eval_branch_quota = ir_build_set_eval_branch_quota(irb, scope, node, arg0_value); 4536 return ir_lval_wrap(irb, scope, set_eval_branch_quota, lval); 4537 } 4538 case BuiltinFnIdAlignCast: 4539 { 4540 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4541 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4542 if (arg0_value == irb->codegen->invalid_instruction) 4543 return arg0_value; 4544 4545 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4546 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4547 if (arg1_value == irb->codegen->invalid_instruction) 4548 return arg1_value; 4549 4550 IrInstruction *align_cast = ir_build_align_cast(irb, scope, node, arg0_value, arg1_value); 4551 return ir_lval_wrap(irb, scope, align_cast, lval); 4552 } 4553 case BuiltinFnIdOpaqueType: 4554 { 4555 IrInstruction *opaque_type = ir_build_opaque_type(irb, scope, node); 4556 return ir_lval_wrap(irb, scope, opaque_type, lval); 4557 } 4558 case BuiltinFnIdThis: 4559 { 4560 IrInstruction *this_inst = ir_gen_this(irb, scope, node); 4561 return ir_lval_wrap(irb, scope, this_inst, lval); 4562 } 4563 case BuiltinFnIdSetAlignStack: 4564 { 4565 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4566 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4567 if (arg0_value == irb->codegen->invalid_instruction) 4568 return arg0_value; 4569 4570 IrInstruction *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value); 4571 return ir_lval_wrap(irb, scope, set_align_stack, lval); 4572 } 4573 case BuiltinFnIdArgType: 4574 { 4575 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4576 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4577 if (arg0_value == irb->codegen->invalid_instruction) 4578 return arg0_value; 4579 4580 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4581 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4582 if (arg1_value == irb->codegen->invalid_instruction) 4583 return arg1_value; 4584 4585 IrInstruction *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value); 4586 return ir_lval_wrap(irb, scope, arg_type, lval); 4587 } 4588 case BuiltinFnIdExport: 4589 { 4590 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4591 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4592 if (arg0_value == irb->codegen->invalid_instruction) 4593 return arg0_value; 4594 4595 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4596 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4597 if (arg1_value == irb->codegen->invalid_instruction) 4598 return arg1_value; 4599 4600 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4601 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4602 if (arg2_value == irb->codegen->invalid_instruction) 4603 return arg2_value; 4604 4605 IrInstruction *ir_export = ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); 4606 return ir_lval_wrap(irb, scope, ir_export, lval); 4607 } 4608 case BuiltinFnIdErrorReturnTrace: 4609 { 4610 IrInstruction *error_return_trace = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::Null); 4611 return ir_lval_wrap(irb, scope, error_return_trace, lval); 4612 } 4613 case BuiltinFnIdAtomicRmw: 4614 { 4615 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4616 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4617 if (arg0_value == irb->codegen->invalid_instruction) 4618 return arg0_value; 4619 4620 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4621 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4622 if (arg1_value == irb->codegen->invalid_instruction) 4623 return arg1_value; 4624 4625 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4626 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4627 if (arg2_value == irb->codegen->invalid_instruction) 4628 return arg2_value; 4629 4630 AstNode *arg3_node = node->data.fn_call_expr.params.at(3); 4631 IrInstruction *arg3_value = ir_gen_node(irb, arg3_node, scope); 4632 if (arg3_value == irb->codegen->invalid_instruction) 4633 return arg3_value; 4634 4635 AstNode *arg4_node = node->data.fn_call_expr.params.at(4); 4636 IrInstruction *arg4_value = ir_gen_node(irb, arg4_node, scope); 4637 if (arg4_value == irb->codegen->invalid_instruction) 4638 return arg4_value; 4639 4640 return ir_build_atomic_rmw(irb, scope, node, arg0_value, arg1_value, arg2_value, arg3_value, 4641 arg4_value, 4642 // these 2 values don't mean anything since we passed non-null values for other args 4643 AtomicRmwOp_xchg, AtomicOrderMonotonic); 4644 } 4645 case BuiltinFnIdAtomicLoad: 4646 { 4647 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4648 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4649 if (arg0_value == irb->codegen->invalid_instruction) 4650 return arg0_value; 4651 4652 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4653 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4654 if (arg1_value == irb->codegen->invalid_instruction) 4655 return arg1_value; 4656 4657 AstNode *arg2_node = node->data.fn_call_expr.params.at(2); 4658 IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); 4659 if (arg2_value == irb->codegen->invalid_instruction) 4660 return arg2_value; 4661 4662 return ir_build_atomic_load(irb, scope, node, arg0_value, arg1_value, arg2_value, 4663 // this value does not mean anything since we passed non-null values for other arg 4664 AtomicOrderMonotonic); 4665 } 4666 case BuiltinFnIdIntToEnum: 4667 { 4668 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4669 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4670 if (arg0_value == irb->codegen->invalid_instruction) 4671 return arg0_value; 4672 4673 AstNode *arg1_node = node->data.fn_call_expr.params.at(1); 4674 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); 4675 if (arg1_value == irb->codegen->invalid_instruction) 4676 return arg1_value; 4677 4678 IrInstruction *result = ir_build_int_to_enum(irb, scope, node, arg0_value, arg1_value); 4679 return ir_lval_wrap(irb, scope, result, lval); 4680 } 4681 case BuiltinFnIdEnumToInt: 4682 { 4683 AstNode *arg0_node = node->data.fn_call_expr.params.at(0); 4684 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); 4685 if (arg0_value == irb->codegen->invalid_instruction) 4686 return arg0_value; 4687 4688 IrInstruction *result = ir_build_enum_to_int(irb, scope, node, arg0_value); 4689 return ir_lval_wrap(irb, scope, result, lval); 4690 } 4691 } 4692 zig_unreachable(); 4693 } 4694 4695 static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 4696 assert(node->type == NodeTypeFnCallExpr); 4697 4698 if (node->data.fn_call_expr.is_builtin) 4699 return ir_gen_builtin_fn_call(irb, scope, node, lval); 4700 4701 AstNode *fn_ref_node = node->data.fn_call_expr.fn_ref_expr; 4702 IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); 4703 if (fn_ref == irb->codegen->invalid_instruction) 4704 return fn_ref; 4705 4706 size_t arg_count = node->data.fn_call_expr.params.length; 4707 IrInstruction **args = allocate<IrInstruction*>(arg_count); 4708 for (size_t i = 0; i < arg_count; i += 1) { 4709 AstNode *arg_node = node->data.fn_call_expr.params.at(i); 4710 args[i] = ir_gen_node(irb, arg_node, scope); 4711 if (args[i] == irb->codegen->invalid_instruction) 4712 return args[i]; 4713 } 4714 4715 bool is_async = node->data.fn_call_expr.is_async; 4716 IrInstruction *async_allocator = nullptr; 4717 if (is_async) { 4718 if (node->data.fn_call_expr.async_allocator) { 4719 async_allocator = ir_gen_node(irb, node->data.fn_call_expr.async_allocator, scope); 4720 if (async_allocator == irb->codegen->invalid_instruction) 4721 return async_allocator; 4722 } 4723 } 4724 4725 IrInstruction *fn_call = ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, FnInlineAuto, is_async, async_allocator, nullptr); 4726 return ir_lval_wrap(irb, scope, fn_call, lval); 4727 } 4728 4729 static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 4730 assert(node->type == NodeTypeIfBoolExpr); 4731 4732 IrInstruction *condition = ir_gen_node(irb, node->data.if_bool_expr.condition, scope); 4733 if (condition == irb->codegen->invalid_instruction) 4734 return condition; 4735 4736 IrInstruction *is_comptime; 4737 if (ir_should_inline(irb->exec, scope)) { 4738 is_comptime = ir_build_const_bool(irb, scope, node, true); 4739 } else { 4740 is_comptime = ir_build_test_comptime(irb, scope, node, condition); 4741 } 4742 4743 AstNode *then_node = node->data.if_bool_expr.then_block; 4744 AstNode *else_node = node->data.if_bool_expr.else_node; 4745 4746 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "Then"); 4747 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "Else"); 4748 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "EndIf"); 4749 4750 ir_build_cond_br(irb, scope, condition->source_node, condition, then_block, else_block, is_comptime); 4751 4752 ir_set_cursor_at_end_and_append_block(irb, then_block); 4753 4754 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 4755 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, subexpr_scope); 4756 if (then_expr_result == irb->codegen->invalid_instruction) 4757 return then_expr_result; 4758 IrBasicBlock *after_then_block = irb->current_basic_block; 4759 if (!instr_is_unreachable(then_expr_result)) 4760 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 4761 4762 ir_set_cursor_at_end_and_append_block(irb, else_block); 4763 IrInstruction *else_expr_result; 4764 if (else_node) { 4765 else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); 4766 if (else_expr_result == irb->codegen->invalid_instruction) 4767 return else_expr_result; 4768 } else { 4769 else_expr_result = ir_build_const_void(irb, scope, node); 4770 } 4771 IrBasicBlock *after_else_block = irb->current_basic_block; 4772 if (!instr_is_unreachable(else_expr_result)) 4773 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 4774 4775 ir_set_cursor_at_end_and_append_block(irb, endif_block); 4776 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 4777 incoming_values[0] = then_expr_result; 4778 incoming_values[1] = else_expr_result; 4779 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 4780 incoming_blocks[0] = after_then_block; 4781 incoming_blocks[1] = after_else_block; 4782 4783 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 4784 } 4785 4786 static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) { 4787 assert(node->type == NodeTypePrefixOpExpr); 4788 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 4789 4790 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); 4791 if (value == irb->codegen->invalid_instruction) 4792 return value; 4793 4794 return ir_build_un_op(irb, scope, node, op_id, value); 4795 } 4796 4797 static IrInstruction *ir_gen_prefix_op_id(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id) { 4798 return ir_gen_prefix_op_id_lval(irb, scope, node, op_id, LValNone); 4799 } 4800 4801 static IrInstruction *ir_lval_wrap(IrBuilder *irb, Scope *scope, IrInstruction *value, LVal lval) { 4802 if (lval != LValPtr) 4803 return value; 4804 if (value == irb->codegen->invalid_instruction) 4805 return value; 4806 4807 // We needed a pointer to a value, but we got a value. So we create 4808 // an instruction which just makes a const pointer of it. 4809 return ir_build_ref(irb, scope, value->source_node, value, false, false); 4810 } 4811 4812 static IrInstruction *ir_gen_pointer_type(IrBuilder *irb, Scope *scope, AstNode *node) { 4813 assert(node->type == NodeTypePointerType); 4814 PtrLen ptr_len = (node->data.pointer_type.star_token->id == TokenIdStar || 4815 node->data.pointer_type.star_token->id == TokenIdStarStar) ? PtrLenSingle : PtrLenUnknown; 4816 bool is_const = node->data.pointer_type.is_const; 4817 bool is_volatile = node->data.pointer_type.is_volatile; 4818 AstNode *expr_node = node->data.pointer_type.op_expr; 4819 AstNode *align_expr = node->data.pointer_type.align_expr; 4820 4821 IrInstruction *align_value; 4822 if (align_expr != nullptr) { 4823 align_value = ir_gen_node(irb, align_expr, scope); 4824 if (align_value == irb->codegen->invalid_instruction) 4825 return align_value; 4826 } else { 4827 align_value = nullptr; 4828 } 4829 4830 IrInstruction *child_type = ir_gen_node(irb, expr_node, scope); 4831 if (child_type == irb->codegen->invalid_instruction) 4832 return child_type; 4833 4834 uint32_t bit_offset_start = 0; 4835 if (node->data.pointer_type.bit_offset_start != nullptr) { 4836 if (!bigint_fits_in_bits(node->data.pointer_type.bit_offset_start, 32, false)) { 4837 Buf *val_buf = buf_alloc(); 4838 bigint_append_buf(val_buf, node->data.pointer_type.bit_offset_start, 10); 4839 exec_add_error_node(irb->codegen, irb->exec, node, 4840 buf_sprintf("value %s too large for u32 bit offset", buf_ptr(val_buf))); 4841 return irb->codegen->invalid_instruction; 4842 } 4843 bit_offset_start = bigint_as_unsigned(node->data.pointer_type.bit_offset_start); 4844 } 4845 4846 uint32_t host_int_bytes = 0; 4847 if (node->data.pointer_type.host_int_bytes != nullptr) { 4848 if (!bigint_fits_in_bits(node->data.pointer_type.host_int_bytes, 32, false)) { 4849 Buf *val_buf = buf_alloc(); 4850 bigint_append_buf(val_buf, node->data.pointer_type.host_int_bytes, 10); 4851 exec_add_error_node(irb->codegen, irb->exec, node, 4852 buf_sprintf("value %s too large for u32 byte count", buf_ptr(val_buf))); 4853 return irb->codegen->invalid_instruction; 4854 } 4855 host_int_bytes = bigint_as_unsigned(node->data.pointer_type.host_int_bytes); 4856 } 4857 4858 if (host_int_bytes != 0 && bit_offset_start >= host_int_bytes * 8) { 4859 exec_add_error_node(irb->codegen, irb->exec, node, 4860 buf_sprintf("bit offset starts after end of host integer")); 4861 return irb->codegen->invalid_instruction; 4862 } 4863 4864 return ir_build_ptr_type(irb, scope, node, child_type, is_const, is_volatile, 4865 ptr_len, align_value, bit_offset_start, host_int_bytes); 4866 } 4867 4868 static IrInstruction *ir_gen_err_assert_ok(IrBuilder *irb, Scope *scope, AstNode *source_node, AstNode *expr_node, 4869 LVal lval) 4870 { 4871 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 4872 if (err_union_ptr == irb->codegen->invalid_instruction) 4873 return irb->codegen->invalid_instruction; 4874 4875 IrInstruction *payload_ptr = ir_build_unwrap_err_payload(irb, scope, source_node, err_union_ptr, true); 4876 if (payload_ptr == irb->codegen->invalid_instruction) 4877 return irb->codegen->invalid_instruction; 4878 4879 if (lval == LValPtr) 4880 return payload_ptr; 4881 4882 return ir_build_load_ptr(irb, scope, source_node, payload_ptr); 4883 } 4884 4885 static IrInstruction *ir_gen_bool_not(IrBuilder *irb, Scope *scope, AstNode *node) { 4886 assert(node->type == NodeTypePrefixOpExpr); 4887 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 4888 4889 IrInstruction *value = ir_gen_node(irb, expr_node, scope); 4890 if (value == irb->codegen->invalid_instruction) 4891 return irb->codegen->invalid_instruction; 4892 4893 return ir_build_bool_not(irb, scope, node, value); 4894 } 4895 4896 static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval) { 4897 assert(node->type == NodeTypePrefixOpExpr); 4898 4899 PrefixOp prefix_op = node->data.prefix_op_expr.prefix_op; 4900 4901 switch (prefix_op) { 4902 case PrefixOpInvalid: 4903 zig_unreachable(); 4904 case PrefixOpBoolNot: 4905 return ir_lval_wrap(irb, scope, ir_gen_bool_not(irb, scope, node), lval); 4906 case PrefixOpBinNot: 4907 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpBinNot), lval); 4908 case PrefixOpNegation: 4909 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegation), lval); 4910 case PrefixOpNegationWrap: 4911 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpNegationWrap), lval); 4912 case PrefixOpOptional: 4913 return ir_lval_wrap(irb, scope, ir_gen_prefix_op_id(irb, scope, node, IrUnOpOptional), lval); 4914 case PrefixOpAddrOf: { 4915 AstNode *expr_node = node->data.prefix_op_expr.primary_expr; 4916 return ir_lval_wrap(irb, scope, ir_gen_node_extra(irb, expr_node, scope, LValPtr), lval); 4917 } 4918 } 4919 zig_unreachable(); 4920 } 4921 4922 static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 4923 assert(node->type == NodeTypeContainerInitExpr); 4924 4925 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr; 4926 ContainerInitKind kind = container_init_expr->kind; 4927 4928 IrInstruction *container_type = ir_gen_node(irb, container_init_expr->type, scope); 4929 if (container_type == irb->codegen->invalid_instruction) 4930 return container_type; 4931 4932 if (kind == ContainerInitKindStruct) { 4933 size_t field_count = container_init_expr->entries.length; 4934 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count); 4935 for (size_t i = 0; i < field_count; i += 1) { 4936 AstNode *entry_node = container_init_expr->entries.at(i); 4937 assert(entry_node->type == NodeTypeStructValueField); 4938 4939 Buf *name = entry_node->data.struct_val_field.name; 4940 AstNode *expr_node = entry_node->data.struct_val_field.expr; 4941 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); 4942 if (expr_value == irb->codegen->invalid_instruction) 4943 return expr_value; 4944 4945 fields[i].name = name; 4946 fields[i].value = expr_value; 4947 fields[i].source_node = entry_node; 4948 } 4949 return ir_build_container_init_fields(irb, scope, node, container_type, field_count, fields); 4950 } else if (kind == ContainerInitKindArray) { 4951 size_t item_count = container_init_expr->entries.length; 4952 IrInstruction **values = allocate<IrInstruction *>(item_count); 4953 for (size_t i = 0; i < item_count; i += 1) { 4954 AstNode *expr_node = container_init_expr->entries.at(i); 4955 IrInstruction *expr_value = ir_gen_node(irb, expr_node, scope); 4956 if (expr_value == irb->codegen->invalid_instruction) 4957 return expr_value; 4958 4959 values[i] = expr_value; 4960 } 4961 return ir_build_container_init_list(irb, scope, node, container_type, item_count, values); 4962 } else { 4963 zig_unreachable(); 4964 } 4965 } 4966 4967 static IrInstruction *ir_gen_var_decl(IrBuilder *irb, Scope *scope, AstNode *node) { 4968 assert(node->type == NodeTypeVariableDeclaration); 4969 4970 AstNodeVariableDeclaration *variable_declaration = &node->data.variable_declaration; 4971 4972 if (buf_eql_str(variable_declaration->symbol, "_")) { 4973 add_node_error(irb->codegen, node, buf_sprintf("`_` is not a declarable symbol")); 4974 return irb->codegen->invalid_instruction; 4975 } 4976 4977 IrInstruction *type_instruction; 4978 if (variable_declaration->type != nullptr) { 4979 type_instruction = ir_gen_node(irb, variable_declaration->type, scope); 4980 if (type_instruction == irb->codegen->invalid_instruction) 4981 return type_instruction; 4982 } else { 4983 type_instruction = nullptr; 4984 } 4985 4986 bool is_shadowable = false; 4987 bool is_const = variable_declaration->is_const; 4988 bool is_extern = variable_declaration->is_extern; 4989 4990 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, 4991 ir_should_inline(irb->exec, scope) || variable_declaration->is_comptime); 4992 ZigVar *var = ir_create_var(irb, node, scope, variable_declaration->symbol, 4993 is_const, is_const, is_shadowable, is_comptime); 4994 // we detect IrInstructionIdDeclVar in gen_block to make sure the next node 4995 // is inside var->child_scope 4996 4997 if (!is_extern && !variable_declaration->expr) { 4998 var->value->type = irb->codegen->builtin_types.entry_invalid; 4999 add_node_error(irb->codegen, node, buf_sprintf("variables must be initialized")); 5000 return irb->codegen->invalid_instruction; 5001 } 5002 5003 IrInstruction *align_value = nullptr; 5004 if (variable_declaration->align_expr != nullptr) { 5005 align_value = ir_gen_node(irb, variable_declaration->align_expr, scope); 5006 if (align_value == irb->codegen->invalid_instruction) 5007 return align_value; 5008 } 5009 5010 if (variable_declaration->section_expr != nullptr) { 5011 add_node_error(irb->codegen, variable_declaration->section_expr, 5012 buf_sprintf("cannot set section of local variable '%s'", buf_ptr(variable_declaration->symbol))); 5013 } 5014 5015 // Temporarily set the name of the IrExecutable to the VariableDeclaration 5016 // so that the struct or enum from the init expression inherits the name. 5017 Buf *old_exec_name = irb->exec->name; 5018 irb->exec->name = variable_declaration->symbol; 5019 IrInstruction *init_value = ir_gen_node(irb, variable_declaration->expr, scope); 5020 irb->exec->name = old_exec_name; 5021 5022 if (init_value == irb->codegen->invalid_instruction) 5023 return init_value; 5024 5025 return ir_build_var_decl(irb, scope, node, var, type_instruction, align_value, init_value); 5026 } 5027 5028 static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5029 assert(node->type == NodeTypeWhileExpr); 5030 5031 AstNode *continue_expr_node = node->data.while_expr.continue_expr; 5032 AstNode *else_node = node->data.while_expr.else_node; 5033 5034 IrBasicBlock *cond_block = ir_create_basic_block(irb, scope, "WhileCond"); 5035 IrBasicBlock *body_block = ir_create_basic_block(irb, scope, "WhileBody"); 5036 IrBasicBlock *continue_block = continue_expr_node ? 5037 ir_create_basic_block(irb, scope, "WhileContinue") : cond_block; 5038 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "WhileEnd"); 5039 IrBasicBlock *else_block = else_node ? 5040 ir_create_basic_block(irb, scope, "WhileElse") : end_block; 5041 5042 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, 5043 ir_should_inline(irb->exec, scope) || node->data.while_expr.is_inline); 5044 ir_build_br(irb, scope, node, cond_block, is_comptime); 5045 5046 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 5047 Buf *var_symbol = node->data.while_expr.var_symbol; 5048 Buf *err_symbol = node->data.while_expr.err_symbol; 5049 if (err_symbol != nullptr) { 5050 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5051 5052 Scope *payload_scope; 5053 AstNode *symbol_node = node; // TODO make more accurate 5054 ZigVar *payload_var; 5055 if (var_symbol) { 5056 // TODO make it an error to write to payload variable 5057 payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 5058 true, false, false, is_comptime); 5059 payload_scope = payload_var->child_scope; 5060 } else { 5061 payload_scope = subexpr_scope; 5062 } 5063 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); 5064 if (err_val_ptr == irb->codegen->invalid_instruction) 5065 return err_val_ptr; 5066 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr); 5067 IrInstruction *is_err = ir_build_test_err(irb, scope, node->data.while_expr.condition, err_val); 5068 IrBasicBlock *after_cond_block = irb->current_basic_block; 5069 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 5070 if (!instr_is_unreachable(is_err)) { 5071 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, 5072 else_block, body_block, is_comptime)); 5073 } 5074 5075 ir_set_cursor_at_end_and_append_block(irb, body_block); 5076 if (var_symbol) { 5077 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, payload_scope, symbol_node, 5078 err_val_ptr, false); 5079 IrInstruction *var_value = node->data.while_expr.var_is_ptr ? 5080 var_ptr_value : ir_build_load_ptr(irb, payload_scope, symbol_node, var_ptr_value); 5081 ir_build_var_decl(irb, payload_scope, symbol_node, payload_var, nullptr, nullptr, var_value); 5082 } 5083 5084 ZigList<IrInstruction *> incoming_values = {0}; 5085 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5086 5087 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, payload_scope); 5088 loop_scope->break_block = end_block; 5089 loop_scope->continue_block = continue_block; 5090 loop_scope->is_comptime = is_comptime; 5091 loop_scope->incoming_blocks = &incoming_blocks; 5092 loop_scope->incoming_values = &incoming_values; 5093 5094 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 5095 if (body_result == irb->codegen->invalid_instruction) 5096 return body_result; 5097 5098 if (!instr_is_unreachable(body_result)) { 5099 ir_mark_gen(ir_build_check_statement_is_void(irb, payload_scope, node->data.while_expr.body, body_result)); 5100 ir_mark_gen(ir_build_br(irb, payload_scope, node, continue_block, is_comptime)); 5101 } 5102 5103 if (continue_expr_node) { 5104 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5105 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, payload_scope); 5106 if (expr_result == irb->codegen->invalid_instruction) 5107 return expr_result; 5108 if (!instr_is_unreachable(expr_result)) 5109 ir_mark_gen(ir_build_br(irb, payload_scope, node, cond_block, is_comptime)); 5110 } 5111 5112 ir_set_cursor_at_end_and_append_block(irb, else_block); 5113 assert(else_node != nullptr); 5114 5115 // TODO make it an error to write to error variable 5116 AstNode *err_symbol_node = else_node; // TODO make more accurate 5117 ZigVar *err_var = ir_create_var(irb, err_symbol_node, scope, err_symbol, 5118 true, false, false, is_comptime); 5119 Scope *err_scope = err_var->child_scope; 5120 IrInstruction *err_var_value = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); 5121 ir_build_var_decl(irb, err_scope, symbol_node, err_var, nullptr, nullptr, err_var_value); 5122 5123 IrInstruction *else_result = ir_gen_node(irb, else_node, err_scope); 5124 if (else_result == irb->codegen->invalid_instruction) 5125 return else_result; 5126 if (!instr_is_unreachable(else_result)) 5127 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 5128 IrBasicBlock *after_else_block = irb->current_basic_block; 5129 ir_set_cursor_at_end_and_append_block(irb, end_block); 5130 if (else_result) { 5131 incoming_blocks.append(after_else_block); 5132 incoming_values.append(else_result); 5133 } else { 5134 incoming_blocks.append(after_cond_block); 5135 incoming_values.append(void_else_result); 5136 } 5137 5138 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5139 } else if (var_symbol != nullptr) { 5140 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5141 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 5142 // TODO make it an error to write to payload variable 5143 AstNode *symbol_node = node; // TODO make more accurate 5144 5145 ZigVar *payload_var = ir_create_var(irb, symbol_node, subexpr_scope, var_symbol, 5146 true, false, false, is_comptime); 5147 Scope *child_scope = payload_var->child_scope; 5148 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, node->data.while_expr.condition, subexpr_scope, LValPtr); 5149 if (maybe_val_ptr == irb->codegen->invalid_instruction) 5150 return maybe_val_ptr; 5151 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); 5152 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); 5153 IrBasicBlock *after_cond_block = irb->current_basic_block; 5154 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 5155 if (!instr_is_unreachable(is_non_null)) { 5156 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, 5157 body_block, else_block, is_comptime)); 5158 } 5159 5160 ir_set_cursor_at_end_and_append_block(irb, body_block); 5161 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, child_scope, symbol_node, maybe_val_ptr, false); 5162 IrInstruction *var_value = node->data.while_expr.var_is_ptr ? 5163 var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value); 5164 ir_build_var_decl(irb, child_scope, symbol_node, payload_var, nullptr, nullptr, var_value); 5165 5166 ZigList<IrInstruction *> incoming_values = {0}; 5167 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5168 5169 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 5170 loop_scope->break_block = end_block; 5171 loop_scope->continue_block = continue_block; 5172 loop_scope->is_comptime = is_comptime; 5173 loop_scope->incoming_blocks = &incoming_blocks; 5174 loop_scope->incoming_values = &incoming_values; 5175 5176 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 5177 if (body_result == irb->codegen->invalid_instruction) 5178 return body_result; 5179 5180 if (!instr_is_unreachable(body_result)) { 5181 ir_mark_gen(ir_build_check_statement_is_void(irb, child_scope, node->data.while_expr.body, body_result)); 5182 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 5183 } 5184 5185 if (continue_expr_node) { 5186 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5187 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, child_scope); 5188 if (expr_result == irb->codegen->invalid_instruction) 5189 return expr_result; 5190 if (!instr_is_unreachable(expr_result)) 5191 ir_mark_gen(ir_build_br(irb, child_scope, node, cond_block, is_comptime)); 5192 } 5193 5194 IrInstruction *else_result = nullptr; 5195 if (else_node) { 5196 ir_set_cursor_at_end_and_append_block(irb, else_block); 5197 5198 else_result = ir_gen_node(irb, else_node, scope); 5199 if (else_result == irb->codegen->invalid_instruction) 5200 return else_result; 5201 if (!instr_is_unreachable(else_result)) 5202 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 5203 } 5204 IrBasicBlock *after_else_block = irb->current_basic_block; 5205 ir_set_cursor_at_end_and_append_block(irb, end_block); 5206 if (else_result) { 5207 incoming_blocks.append(after_else_block); 5208 incoming_values.append(else_result); 5209 } else { 5210 incoming_blocks.append(after_cond_block); 5211 incoming_values.append(void_else_result); 5212 } 5213 5214 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5215 } else { 5216 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5217 IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); 5218 if (cond_val == irb->codegen->invalid_instruction) 5219 return cond_val; 5220 IrBasicBlock *after_cond_block = irb->current_basic_block; 5221 IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); 5222 if (!instr_is_unreachable(cond_val)) { 5223 ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, 5224 body_block, else_block, is_comptime)); 5225 } 5226 5227 ir_set_cursor_at_end_and_append_block(irb, body_block); 5228 5229 ZigList<IrInstruction *> incoming_values = {0}; 5230 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5231 5232 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 5233 5234 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, subexpr_scope); 5235 loop_scope->break_block = end_block; 5236 loop_scope->continue_block = continue_block; 5237 loop_scope->is_comptime = is_comptime; 5238 loop_scope->incoming_blocks = &incoming_blocks; 5239 loop_scope->incoming_values = &incoming_values; 5240 5241 IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, &loop_scope->base); 5242 if (body_result == irb->codegen->invalid_instruction) 5243 return body_result; 5244 5245 if (!instr_is_unreachable(body_result)) { 5246 ir_mark_gen(ir_build_check_statement_is_void(irb, scope, node->data.while_expr.body, body_result)); 5247 ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime)); 5248 } 5249 5250 if (continue_expr_node) { 5251 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5252 IrInstruction *expr_result = ir_gen_node(irb, continue_expr_node, subexpr_scope); 5253 if (expr_result == irb->codegen->invalid_instruction) 5254 return expr_result; 5255 if (!instr_is_unreachable(expr_result)) 5256 ir_mark_gen(ir_build_br(irb, scope, node, cond_block, is_comptime)); 5257 } 5258 5259 IrInstruction *else_result = nullptr; 5260 if (else_node) { 5261 ir_set_cursor_at_end_and_append_block(irb, else_block); 5262 5263 else_result = ir_gen_node(irb, else_node, subexpr_scope); 5264 if (else_result == irb->codegen->invalid_instruction) 5265 return else_result; 5266 if (!instr_is_unreachable(else_result)) 5267 ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); 5268 } 5269 IrBasicBlock *after_else_block = irb->current_basic_block; 5270 ir_set_cursor_at_end_and_append_block(irb, end_block); 5271 if (else_result) { 5272 incoming_blocks.append(after_else_block); 5273 incoming_values.append(else_result); 5274 } else { 5275 incoming_blocks.append(after_cond_block); 5276 incoming_values.append(void_else_result); 5277 } 5278 5279 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5280 } 5281 } 5282 5283 static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 5284 assert(node->type == NodeTypeForExpr); 5285 5286 AstNode *array_node = node->data.for_expr.array_expr; 5287 AstNode *elem_node = node->data.for_expr.elem_node; 5288 AstNode *index_node = node->data.for_expr.index_node; 5289 AstNode *body_node = node->data.for_expr.body; 5290 AstNode *else_node = node->data.for_expr.else_node; 5291 5292 if (!elem_node) { 5293 add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter")); 5294 return irb->codegen->invalid_instruction; 5295 } 5296 assert(elem_node->type == NodeTypeSymbol); 5297 5298 IrInstruction *array_val_ptr = ir_gen_node_extra(irb, array_node, parent_scope, LValPtr); 5299 if (array_val_ptr == irb->codegen->invalid_instruction) 5300 return array_val_ptr; 5301 5302 IrInstruction *array_val = ir_build_load_ptr(irb, parent_scope, array_node, array_val_ptr); 5303 5304 IrInstruction *pointer_type = ir_build_to_ptr_type(irb, parent_scope, array_node, array_val); 5305 IrInstruction *elem_var_type; 5306 if (node->data.for_expr.elem_is_ptr) { 5307 elem_var_type = pointer_type; 5308 } else { 5309 elem_var_type = ir_build_ptr_type_child(irb, parent_scope, elem_node, pointer_type); 5310 } 5311 5312 IrInstruction *is_comptime = ir_build_const_bool(irb, parent_scope, node, 5313 ir_should_inline(irb->exec, parent_scope) || node->data.for_expr.is_inline); 5314 5315 // TODO make it an error to write to element variable or i variable. 5316 Buf *elem_var_name = elem_node->data.symbol_expr.symbol; 5317 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime); 5318 Scope *child_scope = elem_var->child_scope; 5319 5320 IrInstruction *undefined_value = ir_build_const_undefined(irb, child_scope, elem_node); 5321 ir_build_var_decl(irb, child_scope, elem_node, elem_var, elem_var_type, nullptr, undefined_value); 5322 IrInstruction *elem_var_ptr = ir_build_var_ptr(irb, child_scope, node, elem_var); 5323 5324 AstNode *index_var_source_node; 5325 ZigVar *index_var; 5326 if (index_node) { 5327 index_var_source_node = index_node; 5328 Buf *index_var_name = index_node->data.symbol_expr.symbol; 5329 index_var = ir_create_var(irb, index_node, child_scope, index_var_name, true, false, false, is_comptime); 5330 } else { 5331 index_var_source_node = node; 5332 index_var = ir_create_var(irb, node, child_scope, nullptr, true, false, true, is_comptime); 5333 } 5334 child_scope = index_var->child_scope; 5335 5336 IrInstruction *usize = ir_build_const_type(irb, child_scope, node, irb->codegen->builtin_types.entry_usize); 5337 IrInstruction *zero = ir_build_const_usize(irb, child_scope, node, 0); 5338 IrInstruction *one = ir_build_const_usize(irb, child_scope, node, 1); 5339 ir_build_var_decl(irb, child_scope, index_var_source_node, index_var, usize, nullptr, zero); 5340 IrInstruction *index_ptr = ir_build_var_ptr(irb, child_scope, node, index_var); 5341 5342 5343 IrBasicBlock *cond_block = ir_create_basic_block(irb, child_scope, "ForCond"); 5344 IrBasicBlock *body_block = ir_create_basic_block(irb, child_scope, "ForBody"); 5345 IrBasicBlock *end_block = ir_create_basic_block(irb, child_scope, "ForEnd"); 5346 IrBasicBlock *else_block = else_node ? ir_create_basic_block(irb, child_scope, "ForElse") : end_block; 5347 IrBasicBlock *continue_block = ir_create_basic_block(irb, child_scope, "ForContinue"); 5348 5349 IrInstruction *len_val = ir_build_array_len(irb, child_scope, node, array_val); 5350 ir_build_br(irb, child_scope, node, cond_block, is_comptime); 5351 5352 ir_set_cursor_at_end_and_append_block(irb, cond_block); 5353 IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr); 5354 IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); 5355 IrBasicBlock *after_cond_block = irb->current_basic_block; 5356 IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); 5357 ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime)); 5358 5359 ir_set_cursor_at_end_and_append_block(irb, body_block); 5360 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false, PtrLenSingle); 5361 IrInstruction *elem_val; 5362 if (node->data.for_expr.elem_is_ptr) { 5363 elem_val = elem_ptr; 5364 } else { 5365 elem_val = ir_build_load_ptr(irb, child_scope, node, elem_ptr); 5366 } 5367 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val)); 5368 5369 ZigList<IrInstruction *> incoming_values = {0}; 5370 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5371 ScopeLoop *loop_scope = create_loop_scope(irb->codegen, node, child_scope); 5372 loop_scope->break_block = end_block; 5373 loop_scope->continue_block = continue_block; 5374 loop_scope->is_comptime = is_comptime; 5375 loop_scope->incoming_blocks = &incoming_blocks; 5376 loop_scope->incoming_values = &incoming_values; 5377 5378 IrInstruction *body_result = ir_gen_node(irb, body_node, &loop_scope->base); 5379 5380 if (!instr_is_unreachable(body_result)) 5381 ir_mark_gen(ir_build_br(irb, child_scope, node, continue_block, is_comptime)); 5382 5383 ir_set_cursor_at_end_and_append_block(irb, continue_block); 5384 IrInstruction *new_index_val = ir_build_bin_op(irb, child_scope, node, IrBinOpAdd, index_val, one, false); 5385 ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)); 5386 ir_build_br(irb, child_scope, node, cond_block, is_comptime); 5387 5388 IrInstruction *else_result = nullptr; 5389 if (else_node) { 5390 ir_set_cursor_at_end_and_append_block(irb, else_block); 5391 5392 else_result = ir_gen_node(irb, else_node, parent_scope); 5393 if (else_result == irb->codegen->invalid_instruction) 5394 return else_result; 5395 if (!instr_is_unreachable(else_result)) 5396 ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); 5397 } 5398 IrBasicBlock *after_else_block = irb->current_basic_block; 5399 ir_set_cursor_at_end_and_append_block(irb, end_block); 5400 5401 if (else_result) { 5402 incoming_blocks.append(after_else_block); 5403 incoming_values.append(else_result); 5404 } else { 5405 incoming_blocks.append(after_cond_block); 5406 incoming_values.append(void_else_value); 5407 } 5408 5409 return ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5410 } 5411 5412 static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 5413 assert(node->type == NodeTypeBoolLiteral); 5414 return ir_build_const_bool(irb, scope, node, node->data.bool_literal.value); 5415 } 5416 5417 static IrInstruction *ir_gen_string_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 5418 assert(node->type == NodeTypeStringLiteral); 5419 5420 if (node->data.string_literal.c) { 5421 return ir_build_const_c_str_lit(irb, scope, node, node->data.string_literal.buf); 5422 } else { 5423 return ir_build_const_str_lit(irb, scope, node, node->data.string_literal.buf); 5424 } 5425 } 5426 5427 static IrInstruction *ir_gen_array_type(IrBuilder *irb, Scope *scope, AstNode *node) { 5428 assert(node->type == NodeTypeArrayType); 5429 5430 AstNode *size_node = node->data.array_type.size; 5431 AstNode *child_type_node = node->data.array_type.child_type; 5432 bool is_const = node->data.array_type.is_const; 5433 bool is_volatile = node->data.array_type.is_volatile; 5434 AstNode *align_expr = node->data.array_type.align_expr; 5435 5436 if (size_node) { 5437 if (is_const) { 5438 add_node_error(irb->codegen, node, buf_create_from_str("const qualifier invalid on array type")); 5439 return irb->codegen->invalid_instruction; 5440 } 5441 if (is_volatile) { 5442 add_node_error(irb->codegen, node, buf_create_from_str("volatile qualifier invalid on array type")); 5443 return irb->codegen->invalid_instruction; 5444 } 5445 if (align_expr != nullptr) { 5446 add_node_error(irb->codegen, node, buf_create_from_str("align qualifier invalid on array type")); 5447 return irb->codegen->invalid_instruction; 5448 } 5449 5450 IrInstruction *size_value = ir_gen_node(irb, size_node, scope); 5451 if (size_value == irb->codegen->invalid_instruction) 5452 return size_value; 5453 5454 IrInstruction *child_type = ir_gen_node(irb, child_type_node, scope); 5455 if (child_type == irb->codegen->invalid_instruction) 5456 return child_type; 5457 5458 return ir_build_array_type(irb, scope, node, size_value, child_type); 5459 } else { 5460 IrInstruction *align_value; 5461 if (align_expr != nullptr) { 5462 align_value = ir_gen_node(irb, align_expr, scope); 5463 if (align_value == irb->codegen->invalid_instruction) 5464 return align_value; 5465 } else { 5466 align_value = nullptr; 5467 } 5468 5469 IrInstruction *child_type = ir_gen_node(irb, child_type_node, scope); 5470 if (child_type == irb->codegen->invalid_instruction) 5471 return child_type; 5472 5473 return ir_build_slice_type(irb, scope, node, child_type, is_const, is_volatile, align_value); 5474 } 5475 } 5476 5477 static IrInstruction *ir_gen_promise_type(IrBuilder *irb, Scope *scope, AstNode *node) { 5478 assert(node->type == NodeTypePromiseType); 5479 5480 AstNode *payload_type_node = node->data.promise_type.payload_type; 5481 IrInstruction *payload_type_value = nullptr; 5482 5483 if (payload_type_node != nullptr) { 5484 payload_type_value = ir_gen_node(irb, payload_type_node, scope); 5485 if (payload_type_value == irb->codegen->invalid_instruction) 5486 return payload_type_value; 5487 5488 } 5489 5490 return ir_build_promise_type(irb, scope, node, payload_type_value); 5491 } 5492 5493 static IrInstruction *ir_gen_undefined_literal(IrBuilder *irb, Scope *scope, AstNode *node) { 5494 assert(node->type == NodeTypeUndefinedLiteral); 5495 return ir_build_const_undefined(irb, scope, node); 5496 } 5497 5498 static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5499 assert(node->type == NodeTypeAsmExpr); 5500 5501 IrInstruction **input_list = allocate<IrInstruction *>(node->data.asm_expr.input_list.length); 5502 IrInstruction **output_types = allocate<IrInstruction *>(node->data.asm_expr.output_list.length); 5503 ZigVar **output_vars = allocate<ZigVar *>(node->data.asm_expr.output_list.length); 5504 size_t return_count = 0; 5505 bool is_volatile = node->data.asm_expr.is_volatile; 5506 if (!is_volatile && node->data.asm_expr.output_list.length == 0) { 5507 add_node_error(irb->codegen, node, 5508 buf_sprintf("assembly expression with no output must be marked volatile")); 5509 return irb->codegen->invalid_instruction; 5510 } 5511 for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1) { 5512 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i); 5513 if (asm_output->return_type) { 5514 return_count += 1; 5515 5516 IrInstruction *return_type = ir_gen_node(irb, asm_output->return_type, scope); 5517 if (return_type == irb->codegen->invalid_instruction) 5518 return irb->codegen->invalid_instruction; 5519 if (return_count > 1) { 5520 add_node_error(irb->codegen, node, 5521 buf_sprintf("inline assembly allows up to one output value")); 5522 return irb->codegen->invalid_instruction; 5523 } 5524 output_types[i] = return_type; 5525 } else { 5526 Buf *variable_name = asm_output->variable_name; 5527 // TODO there is some duplication here with ir_gen_symbol. I need to do a full audit of how 5528 // inline assembly works. https://github.com/ziglang/zig/issues/215 5529 ZigVar *var = find_variable(irb->codegen, scope, variable_name, nullptr); 5530 if (var) { 5531 output_vars[i] = var; 5532 } else { 5533 add_node_error(irb->codegen, node, 5534 buf_sprintf("use of undeclared identifier '%s'", buf_ptr(variable_name))); 5535 return irb->codegen->invalid_instruction; 5536 } 5537 } 5538 } 5539 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) { 5540 AsmInput *asm_input = node->data.asm_expr.input_list.at(i); 5541 IrInstruction *input_value = ir_gen_node(irb, asm_input->expr, scope); 5542 if (input_value == irb->codegen->invalid_instruction) 5543 return irb->codegen->invalid_instruction; 5544 5545 input_list[i] = input_value; 5546 } 5547 5548 return ir_build_asm(irb, scope, node, input_list, output_types, output_vars, return_count, is_volatile); 5549 } 5550 5551 static IrInstruction *ir_gen_test_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5552 assert(node->type == NodeTypeTestExpr); 5553 5554 Buf *var_symbol = node->data.test_expr.var_symbol; 5555 AstNode *expr_node = node->data.test_expr.target_node; 5556 AstNode *then_node = node->data.test_expr.then_node; 5557 AstNode *else_node = node->data.test_expr.else_node; 5558 bool var_is_ptr = node->data.test_expr.var_is_ptr; 5559 5560 IrInstruction *maybe_val_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 5561 if (maybe_val_ptr == irb->codegen->invalid_instruction) 5562 return maybe_val_ptr; 5563 5564 IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node, maybe_val_ptr); 5565 IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node, maybe_val); 5566 5567 IrBasicBlock *then_block = ir_create_basic_block(irb, scope, "OptionalThen"); 5568 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "OptionalElse"); 5569 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "OptionalEndIf"); 5570 5571 IrInstruction *is_comptime; 5572 if (ir_should_inline(irb->exec, scope)) { 5573 is_comptime = ir_build_const_bool(irb, scope, node, true); 5574 } else { 5575 is_comptime = ir_build_test_comptime(irb, scope, node, is_non_null); 5576 } 5577 ir_build_cond_br(irb, scope, node, is_non_null, then_block, else_block, is_comptime); 5578 5579 ir_set_cursor_at_end_and_append_block(irb, then_block); 5580 5581 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 5582 Scope *var_scope; 5583 if (var_symbol) { 5584 IrInstruction *var_type = nullptr; 5585 bool is_shadowable = false; 5586 bool is_const = true; 5587 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 5588 var_symbol, is_const, is_const, is_shadowable, is_comptime); 5589 5590 IrInstruction *var_ptr_value = ir_build_unwrap_maybe(irb, subexpr_scope, node, maybe_val_ptr, false); 5591 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); 5592 ir_build_var_decl(irb, subexpr_scope, node, var, var_type, nullptr, var_value); 5593 var_scope = var->child_scope; 5594 } else { 5595 var_scope = subexpr_scope; 5596 } 5597 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); 5598 if (then_expr_result == irb->codegen->invalid_instruction) 5599 return then_expr_result; 5600 IrBasicBlock *after_then_block = irb->current_basic_block; 5601 if (!instr_is_unreachable(then_expr_result)) 5602 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5603 5604 ir_set_cursor_at_end_and_append_block(irb, else_block); 5605 IrInstruction *else_expr_result; 5606 if (else_node) { 5607 else_expr_result = ir_gen_node(irb, else_node, subexpr_scope); 5608 if (else_expr_result == irb->codegen->invalid_instruction) 5609 return else_expr_result; 5610 } else { 5611 else_expr_result = ir_build_const_void(irb, scope, node); 5612 } 5613 IrBasicBlock *after_else_block = irb->current_basic_block; 5614 if (!instr_is_unreachable(else_expr_result)) 5615 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5616 5617 ir_set_cursor_at_end_and_append_block(irb, endif_block); 5618 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 5619 incoming_values[0] = then_expr_result; 5620 incoming_values[1] = else_expr_result; 5621 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 5622 incoming_blocks[0] = after_then_block; 5623 incoming_blocks[1] = after_else_block; 5624 5625 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 5626 } 5627 5628 static IrInstruction *ir_gen_if_err_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5629 assert(node->type == NodeTypeIfErrorExpr); 5630 5631 AstNode *target_node = node->data.if_err_expr.target_node; 5632 AstNode *then_node = node->data.if_err_expr.then_node; 5633 AstNode *else_node = node->data.if_err_expr.else_node; 5634 bool var_is_ptr = node->data.if_err_expr.var_is_ptr; 5635 bool var_is_const = true; 5636 Buf *var_symbol = node->data.if_err_expr.var_symbol; 5637 Buf *err_symbol = node->data.if_err_expr.err_symbol; 5638 5639 IrInstruction *err_val_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); 5640 if (err_val_ptr == irb->codegen->invalid_instruction) 5641 return err_val_ptr; 5642 5643 IrInstruction *err_val = ir_build_load_ptr(irb, scope, node, err_val_ptr); 5644 IrInstruction *is_err = ir_build_test_err(irb, scope, node, err_val); 5645 5646 IrBasicBlock *ok_block = ir_create_basic_block(irb, scope, "TryOk"); 5647 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "TryElse"); 5648 IrBasicBlock *endif_block = ir_create_basic_block(irb, scope, "TryEnd"); 5649 5650 bool force_comptime = ir_should_inline(irb->exec, scope); 5651 IrInstruction *is_comptime = force_comptime ? ir_build_const_bool(irb, scope, node, true) : ir_build_test_comptime(irb, scope, node, is_err); 5652 ir_build_cond_br(irb, scope, node, is_err, else_block, ok_block, is_comptime); 5653 5654 ir_set_cursor_at_end_and_append_block(irb, ok_block); 5655 5656 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 5657 Scope *var_scope; 5658 if (var_symbol) { 5659 IrInstruction *var_type = nullptr; 5660 bool is_shadowable = false; 5661 IrInstruction *var_is_comptime = force_comptime ? ir_build_const_bool(irb, subexpr_scope, node, true) : ir_build_test_comptime(irb, subexpr_scope, node, err_val); 5662 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 5663 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime); 5664 5665 IrInstruction *var_ptr_value = ir_build_unwrap_err_payload(irb, subexpr_scope, node, err_val_ptr, false); 5666 IrInstruction *var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, subexpr_scope, node, var_ptr_value); 5667 ir_build_var_decl(irb, subexpr_scope, node, var, var_type, nullptr, var_value); 5668 var_scope = var->child_scope; 5669 } else { 5670 var_scope = subexpr_scope; 5671 } 5672 IrInstruction *then_expr_result = ir_gen_node(irb, then_node, var_scope); 5673 if (then_expr_result == irb->codegen->invalid_instruction) 5674 return then_expr_result; 5675 IrBasicBlock *after_then_block = irb->current_basic_block; 5676 if (!instr_is_unreachable(then_expr_result)) 5677 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5678 5679 ir_set_cursor_at_end_and_append_block(irb, else_block); 5680 5681 IrInstruction *else_expr_result; 5682 if (else_node) { 5683 Scope *err_var_scope; 5684 if (err_symbol) { 5685 IrInstruction *var_type = nullptr; 5686 bool is_shadowable = false; 5687 bool is_const = true; 5688 ZigVar *var = ir_create_var(irb, node, subexpr_scope, 5689 err_symbol, is_const, is_const, is_shadowable, is_comptime); 5690 5691 IrInstruction *var_value = ir_build_unwrap_err_code(irb, subexpr_scope, node, err_val_ptr); 5692 ir_build_var_decl(irb, subexpr_scope, node, var, var_type, nullptr, var_value); 5693 err_var_scope = var->child_scope; 5694 } else { 5695 err_var_scope = subexpr_scope; 5696 } 5697 else_expr_result = ir_gen_node(irb, else_node, err_var_scope); 5698 if (else_expr_result == irb->codegen->invalid_instruction) 5699 return else_expr_result; 5700 } else { 5701 else_expr_result = ir_build_const_void(irb, scope, node); 5702 } 5703 IrBasicBlock *after_else_block = irb->current_basic_block; 5704 if (!instr_is_unreachable(else_expr_result)) 5705 ir_mark_gen(ir_build_br(irb, scope, node, endif_block, is_comptime)); 5706 5707 ir_set_cursor_at_end_and_append_block(irb, endif_block); 5708 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 5709 incoming_values[0] = then_expr_result; 5710 incoming_values[1] = else_expr_result; 5711 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 5712 incoming_blocks[0] = after_then_block; 5713 incoming_blocks[1] = after_else_block; 5714 5715 return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 5716 } 5717 5718 static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *switch_node, AstNode *prong_node, 5719 IrBasicBlock *end_block, IrInstruction *is_comptime, IrInstruction *var_is_comptime, 5720 IrInstruction *target_value_ptr, IrInstruction *prong_value, 5721 ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values) 5722 { 5723 assert(switch_node->type == NodeTypeSwitchExpr); 5724 assert(prong_node->type == NodeTypeSwitchProng); 5725 5726 AstNode *expr_node = prong_node->data.switch_prong.expr; 5727 AstNode *var_symbol_node = prong_node->data.switch_prong.var_symbol; 5728 Scope *child_scope; 5729 if (var_symbol_node) { 5730 assert(var_symbol_node->type == NodeTypeSymbol); 5731 Buf *var_name = var_symbol_node->data.symbol_expr.symbol; 5732 bool var_is_ptr = prong_node->data.switch_prong.var_is_ptr; 5733 5734 bool is_shadowable = false; 5735 bool is_const = true; 5736 ZigVar *var = ir_create_var(irb, var_symbol_node, scope, 5737 var_name, is_const, is_const, is_shadowable, var_is_comptime); 5738 child_scope = var->child_scope; 5739 IrInstruction *var_value; 5740 if (prong_value) { 5741 IrInstruction *var_ptr_value = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr, prong_value); 5742 var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); 5743 } else { 5744 var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr); 5745 } 5746 IrInstruction *var_type = nullptr; // infer the type 5747 ir_build_var_decl(irb, scope, var_symbol_node, var, var_type, nullptr, var_value); 5748 } else { 5749 child_scope = scope; 5750 } 5751 5752 IrInstruction *expr_result = ir_gen_node(irb, expr_node, child_scope); 5753 if (expr_result == irb->codegen->invalid_instruction) 5754 return false; 5755 if (!instr_is_unreachable(expr_result)) 5756 ir_mark_gen(ir_build_br(irb, scope, switch_node, end_block, is_comptime)); 5757 incoming_blocks->append(irb->current_basic_block); 5758 incoming_values->append(expr_result); 5759 return true; 5760 } 5761 5762 static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 5763 assert(node->type == NodeTypeSwitchExpr); 5764 5765 AstNode *target_node = node->data.switch_expr.expr; 5766 IrInstruction *target_value_ptr = ir_gen_node_extra(irb, target_node, scope, LValPtr); 5767 if (target_value_ptr == irb->codegen->invalid_instruction) 5768 return target_value_ptr; 5769 IrInstruction *target_value = ir_build_switch_target(irb, scope, node, target_value_ptr); 5770 5771 IrBasicBlock *else_block = ir_create_basic_block(irb, scope, "SwitchElse"); 5772 IrBasicBlock *end_block = ir_create_basic_block(irb, scope, "SwitchEnd"); 5773 5774 size_t prong_count = node->data.switch_expr.prongs.length; 5775 ZigList<IrInstructionSwitchBrCase> cases = {0}; 5776 5777 IrInstruction *is_comptime; 5778 IrInstruction *var_is_comptime; 5779 if (ir_should_inline(irb->exec, scope)) { 5780 is_comptime = ir_build_const_bool(irb, scope, node, true); 5781 var_is_comptime = is_comptime; 5782 } else { 5783 is_comptime = ir_build_test_comptime(irb, scope, node, target_value); 5784 var_is_comptime = ir_build_test_comptime(irb, scope, node, target_value_ptr); 5785 } 5786 5787 ZigList<IrInstruction *> incoming_values = {0}; 5788 ZigList<IrBasicBlock *> incoming_blocks = {0}; 5789 ZigList<IrInstructionCheckSwitchProngsRange> check_ranges = {0}; 5790 5791 // First do the else and the ranges 5792 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime); 5793 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope); 5794 AstNode *else_prong = nullptr; 5795 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 5796 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 5797 size_t prong_item_count = prong_node->data.switch_prong.items.length; 5798 if (prong_item_count == 0) { 5799 if (else_prong) { 5800 ErrorMsg *msg = add_node_error(irb->codegen, prong_node, 5801 buf_sprintf("multiple else prongs in switch expression")); 5802 add_error_note(irb->codegen, msg, else_prong, 5803 buf_sprintf("previous else prong is here")); 5804 return irb->codegen->invalid_instruction; 5805 } 5806 else_prong = prong_node; 5807 5808 IrBasicBlock *prev_block = irb->current_basic_block; 5809 ir_set_cursor_at_end_and_append_block(irb, else_block); 5810 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 5811 is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values)) 5812 { 5813 return irb->codegen->invalid_instruction; 5814 } 5815 ir_set_cursor_at_end(irb, prev_block); 5816 } else if (prong_node->data.switch_prong.any_items_are_range) { 5817 IrInstruction *ok_bit = nullptr; 5818 AstNode *last_item_node = nullptr; 5819 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 5820 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 5821 last_item_node = item_node; 5822 if (item_node->type == NodeTypeSwitchRange) { 5823 AstNode *start_node = item_node->data.switch_range.start; 5824 AstNode *end_node = item_node->data.switch_range.end; 5825 5826 IrInstruction *start_value = ir_gen_node(irb, start_node, comptime_scope); 5827 if (start_value == irb->codegen->invalid_instruction) 5828 return irb->codegen->invalid_instruction; 5829 5830 IrInstruction *end_value = ir_gen_node(irb, end_node, comptime_scope); 5831 if (end_value == irb->codegen->invalid_instruction) 5832 return irb->codegen->invalid_instruction; 5833 5834 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 5835 check_range->start = start_value; 5836 check_range->end = end_value; 5837 5838 IrInstruction *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq, 5839 target_value, start_value, false); 5840 IrInstruction *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq, 5841 target_value, end_value, false); 5842 IrInstruction *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd, 5843 lower_range_ok, upper_range_ok, false); 5844 if (ok_bit) { 5845 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, both_ok, ok_bit, false); 5846 } else { 5847 ok_bit = both_ok; 5848 } 5849 } else { 5850 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); 5851 if (item_value == irb->codegen->invalid_instruction) 5852 return irb->codegen->invalid_instruction; 5853 5854 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 5855 check_range->start = item_value; 5856 check_range->end = item_value; 5857 5858 IrInstruction *cmp_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpEq, 5859 item_value, target_value, false); 5860 if (ok_bit) { 5861 ok_bit = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolOr, cmp_ok, ok_bit, false); 5862 } else { 5863 ok_bit = cmp_ok; 5864 } 5865 } 5866 } 5867 5868 IrBasicBlock *range_block_yes = ir_create_basic_block(irb, scope, "SwitchRangeYes"); 5869 IrBasicBlock *range_block_no = ir_create_basic_block(irb, scope, "SwitchRangeNo"); 5870 5871 assert(ok_bit); 5872 assert(last_item_node); 5873 ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes, 5874 range_block_no, is_comptime)); 5875 5876 ir_set_cursor_at_end_and_append_block(irb, range_block_yes); 5877 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 5878 is_comptime, var_is_comptime, target_value_ptr, nullptr, &incoming_blocks, &incoming_values)) 5879 { 5880 return irb->codegen->invalid_instruction; 5881 } 5882 5883 ir_set_cursor_at_end_and_append_block(irb, range_block_no); 5884 } 5885 } 5886 5887 // next do the non-else non-ranges 5888 for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { 5889 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); 5890 size_t prong_item_count = prong_node->data.switch_prong.items.length; 5891 if (prong_item_count == 0) 5892 continue; 5893 if (prong_node->data.switch_prong.any_items_are_range) 5894 continue; 5895 5896 IrBasicBlock *prong_block = ir_create_basic_block(irb, scope, "SwitchProng"); 5897 IrInstruction *last_item_value = nullptr; 5898 5899 for (size_t item_i = 0; item_i < prong_item_count; item_i += 1) { 5900 AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); 5901 assert(item_node->type != NodeTypeSwitchRange); 5902 5903 IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); 5904 if (item_value == irb->codegen->invalid_instruction) 5905 return irb->codegen->invalid_instruction; 5906 5907 IrInstructionCheckSwitchProngsRange *check_range = check_ranges.add_one(); 5908 check_range->start = item_value; 5909 check_range->end = item_value; 5910 5911 IrInstructionSwitchBrCase *this_case = cases.add_one(); 5912 this_case->value = item_value; 5913 this_case->block = prong_block; 5914 5915 last_item_value = item_value; 5916 } 5917 IrInstruction *only_item_value = (prong_item_count == 1) ? last_item_value : nullptr; 5918 5919 IrBasicBlock *prev_block = irb->current_basic_block; 5920 ir_set_cursor_at_end_and_append_block(irb, prong_block); 5921 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, 5922 is_comptime, var_is_comptime, target_value_ptr, only_item_value, &incoming_blocks, &incoming_values)) 5923 { 5924 return irb->codegen->invalid_instruction; 5925 } 5926 5927 ir_set_cursor_at_end(irb, prev_block); 5928 5929 } 5930 5931 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value, check_ranges.items, check_ranges.length, 5932 else_prong != nullptr); 5933 5934 if (cases.length == 0) { 5935 ir_build_br(irb, scope, node, else_block, is_comptime); 5936 } else { 5937 ir_build_switch_br(irb, scope, node, target_value, else_block, cases.length, cases.items, is_comptime, switch_prongs_void); 5938 } 5939 5940 if (!else_prong) { 5941 ir_set_cursor_at_end_and_append_block(irb, else_block); 5942 ir_build_unreachable(irb, scope, node); 5943 } 5944 5945 ir_set_cursor_at_end_and_append_block(irb, end_block); 5946 assert(incoming_blocks.length == incoming_values.length); 5947 if (incoming_blocks.length == 0) { 5948 return ir_build_const_void(irb, scope, node); 5949 } else { 5950 return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); 5951 } 5952 } 5953 5954 static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { 5955 assert(node->type == NodeTypeCompTime); 5956 5957 Scope *child_scope = create_comptime_scope(irb->codegen, node, parent_scope); 5958 return ir_gen_node_extra(irb, node->data.comptime_expr.expr, child_scope, lval); 5959 } 5960 5961 static IrInstruction *ir_gen_return_from_block(IrBuilder *irb, Scope *break_scope, AstNode *node, ScopeBlock *block_scope) { 5962 IrInstruction *is_comptime; 5963 if (ir_should_inline(irb->exec, break_scope)) { 5964 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 5965 } else { 5966 is_comptime = block_scope->is_comptime; 5967 } 5968 5969 IrInstruction *result_value; 5970 if (node->data.break_expr.expr) { 5971 result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); 5972 if (result_value == irb->codegen->invalid_instruction) 5973 return irb->codegen->invalid_instruction; 5974 } else { 5975 result_value = ir_build_const_void(irb, break_scope, node); 5976 } 5977 5978 IrBasicBlock *dest_block = block_scope->end_block; 5979 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 5980 5981 block_scope->incoming_blocks->append(irb->current_basic_block); 5982 block_scope->incoming_values->append(result_value); 5983 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 5984 } 5985 5986 static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *break_scope, AstNode *node) { 5987 assert(node->type == NodeTypeBreak); 5988 5989 // Search up the scope. We'll find one of these things first: 5990 // * function definition scope or global scope => error, break outside loop 5991 // * defer expression scope => error, cannot break out of defer expression 5992 // * loop scope => OK 5993 // * (if it's a labeled break) labeled block => OK 5994 5995 Scope *search_scope = break_scope; 5996 ScopeLoop *loop_scope; 5997 for (;;) { 5998 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 5999 if (node->data.break_expr.name != nullptr) { 6000 add_node_error(irb->codegen, node, buf_sprintf("label not found: '%s'", buf_ptr(node->data.break_expr.name))); 6001 return irb->codegen->invalid_instruction; 6002 } else { 6003 add_node_error(irb->codegen, node, buf_sprintf("break expression outside loop")); 6004 return irb->codegen->invalid_instruction; 6005 } 6006 } else if (search_scope->id == ScopeIdDeferExpr) { 6007 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of defer expression")); 6008 return irb->codegen->invalid_instruction; 6009 } else if (search_scope->id == ScopeIdLoop) { 6010 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 6011 if (node->data.break_expr.name == nullptr || 6012 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_loop_scope->name))) 6013 { 6014 loop_scope = this_loop_scope; 6015 break; 6016 } 6017 } else if (search_scope->id == ScopeIdBlock) { 6018 ScopeBlock *this_block_scope = (ScopeBlock *)search_scope; 6019 if (node->data.break_expr.name != nullptr && 6020 (this_block_scope->name != nullptr && buf_eql_buf(node->data.break_expr.name, this_block_scope->name))) 6021 { 6022 assert(this_block_scope->end_block != nullptr); 6023 return ir_gen_return_from_block(irb, break_scope, node, this_block_scope); 6024 } 6025 } else if (search_scope->id == ScopeIdSuspend) { 6026 add_node_error(irb->codegen, node, buf_sprintf("cannot break out of suspend block")); 6027 return irb->codegen->invalid_instruction; 6028 } 6029 search_scope = search_scope->parent; 6030 } 6031 6032 IrInstruction *is_comptime; 6033 if (ir_should_inline(irb->exec, break_scope)) { 6034 is_comptime = ir_build_const_bool(irb, break_scope, node, true); 6035 } else { 6036 is_comptime = loop_scope->is_comptime; 6037 } 6038 6039 IrInstruction *result_value; 6040 if (node->data.break_expr.expr) { 6041 result_value = ir_gen_node(irb, node->data.break_expr.expr, break_scope); 6042 if (result_value == irb->codegen->invalid_instruction) 6043 return irb->codegen->invalid_instruction; 6044 } else { 6045 result_value = ir_build_const_void(irb, break_scope, node); 6046 } 6047 6048 IrBasicBlock *dest_block = loop_scope->break_block; 6049 ir_gen_defers_for_block(irb, break_scope, dest_block->scope, false); 6050 6051 loop_scope->incoming_blocks->append(irb->current_basic_block); 6052 loop_scope->incoming_values->append(result_value); 6053 return ir_build_br(irb, break_scope, node, dest_block, is_comptime); 6054 } 6055 6056 static IrInstruction *ir_gen_continue(IrBuilder *irb, Scope *continue_scope, AstNode *node) { 6057 assert(node->type == NodeTypeContinue); 6058 6059 // Search up the scope. We'll find one of these things first: 6060 // * function definition scope or global scope => error, break outside loop 6061 // * defer expression scope => error, cannot break out of defer expression 6062 // * loop scope => OK 6063 6064 ZigList<ScopeRuntime *> runtime_scopes = {}; 6065 6066 Scope *search_scope = continue_scope; 6067 ScopeLoop *loop_scope; 6068 for (;;) { 6069 if (search_scope == nullptr || search_scope->id == ScopeIdFnDef) { 6070 if (node->data.continue_expr.name != nullptr) { 6071 add_node_error(irb->codegen, node, buf_sprintf("labeled loop not found: '%s'", buf_ptr(node->data.continue_expr.name))); 6072 return irb->codegen->invalid_instruction; 6073 } else { 6074 add_node_error(irb->codegen, node, buf_sprintf("continue expression outside loop")); 6075 return irb->codegen->invalid_instruction; 6076 } 6077 } else if (search_scope->id == ScopeIdDeferExpr) { 6078 add_node_error(irb->codegen, node, buf_sprintf("cannot continue out of defer expression")); 6079 return irb->codegen->invalid_instruction; 6080 } else if (search_scope->id == ScopeIdLoop) { 6081 ScopeLoop *this_loop_scope = (ScopeLoop *)search_scope; 6082 if (node->data.continue_expr.name == nullptr || 6083 (this_loop_scope->name != nullptr && buf_eql_buf(node->data.continue_expr.name, this_loop_scope->name))) 6084 { 6085 loop_scope = this_loop_scope; 6086 break; 6087 } 6088 } else if (search_scope->id == ScopeIdRuntime) { 6089 ScopeRuntime *scope_runtime = (ScopeRuntime *)search_scope; 6090 runtime_scopes.append(scope_runtime); 6091 } 6092 search_scope = search_scope->parent; 6093 } 6094 6095 IrInstruction *is_comptime; 6096 if (ir_should_inline(irb->exec, continue_scope)) { 6097 is_comptime = ir_build_const_bool(irb, continue_scope, node, true); 6098 } else { 6099 is_comptime = loop_scope->is_comptime; 6100 } 6101 6102 for (size_t i = 0; i < runtime_scopes.length; i += 1) { 6103 ScopeRuntime *scope_runtime = runtime_scopes.at(i); 6104 ir_mark_gen(ir_build_check_runtime_scope(irb, continue_scope, node, scope_runtime->is_comptime, is_comptime)); 6105 } 6106 6107 IrBasicBlock *dest_block = loop_scope->continue_block; 6108 ir_gen_defers_for_block(irb, continue_scope, dest_block->scope, false); 6109 return ir_mark_gen(ir_build_br(irb, continue_scope, node, dest_block, is_comptime)); 6110 } 6111 6112 static IrInstruction *ir_gen_error_type(IrBuilder *irb, Scope *scope, AstNode *node) { 6113 assert(node->type == NodeTypeErrorType); 6114 return ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_global_error_set); 6115 } 6116 6117 static IrInstruction *ir_gen_defer(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6118 assert(node->type == NodeTypeDefer); 6119 6120 ScopeDefer *defer_child_scope = create_defer_scope(irb->codegen, node, parent_scope); 6121 node->data.defer.child_scope = &defer_child_scope->base; 6122 6123 ScopeDeferExpr *defer_expr_scope = create_defer_expr_scope(irb->codegen, node, parent_scope); 6124 node->data.defer.expr_scope = &defer_expr_scope->base; 6125 6126 return ir_build_const_void(irb, parent_scope, node); 6127 } 6128 6129 static IrInstruction *ir_gen_slice(IrBuilder *irb, Scope *scope, AstNode *node) { 6130 assert(node->type == NodeTypeSliceExpr); 6131 6132 AstNodeSliceExpr *slice_expr = &node->data.slice_expr; 6133 AstNode *array_node = slice_expr->array_ref_expr; 6134 AstNode *start_node = slice_expr->start; 6135 AstNode *end_node = slice_expr->end; 6136 6137 IrInstruction *ptr_value = ir_gen_node_extra(irb, array_node, scope, LValPtr); 6138 if (ptr_value == irb->codegen->invalid_instruction) 6139 return irb->codegen->invalid_instruction; 6140 6141 IrInstruction *start_value = ir_gen_node(irb, start_node, scope); 6142 if (start_value == irb->codegen->invalid_instruction) 6143 return irb->codegen->invalid_instruction; 6144 6145 IrInstruction *end_value; 6146 if (end_node) { 6147 end_value = ir_gen_node(irb, end_node, scope); 6148 if (end_value == irb->codegen->invalid_instruction) 6149 return irb->codegen->invalid_instruction; 6150 } else { 6151 end_value = nullptr; 6152 } 6153 6154 return ir_build_slice(irb, scope, node, ptr_value, start_value, end_value, true); 6155 } 6156 6157 static IrInstruction *ir_gen_err_ok_or(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6158 assert(node->type == NodeTypeUnwrapErrorExpr); 6159 6160 AstNode *op1_node = node->data.unwrap_err_expr.op1; 6161 AstNode *op2_node = node->data.unwrap_err_expr.op2; 6162 AstNode *var_node = node->data.unwrap_err_expr.symbol; 6163 6164 if (op2_node->type == NodeTypeUnreachable) { 6165 if (var_node != nullptr) { 6166 assert(var_node->type == NodeTypeSymbol); 6167 Buf *var_name = var_node->data.symbol_expr.symbol; 6168 add_node_error(irb->codegen, var_node, buf_sprintf("unused variable: '%s'", buf_ptr(var_name))); 6169 return irb->codegen->invalid_instruction; 6170 } 6171 return ir_gen_err_assert_ok(irb, parent_scope, node, op1_node, LValNone); 6172 } 6173 6174 6175 IrInstruction *err_union_ptr = ir_gen_node_extra(irb, op1_node, parent_scope, LValPtr); 6176 if (err_union_ptr == irb->codegen->invalid_instruction) 6177 return irb->codegen->invalid_instruction; 6178 6179 IrInstruction *err_union_val = ir_build_load_ptr(irb, parent_scope, node, err_union_ptr); 6180 IrInstruction *is_err = ir_build_test_err(irb, parent_scope, node, err_union_val); 6181 6182 IrInstruction *is_comptime; 6183 if (ir_should_inline(irb->exec, parent_scope)) { 6184 is_comptime = ir_build_const_bool(irb, parent_scope, node, true); 6185 } else { 6186 is_comptime = ir_build_test_comptime(irb, parent_scope, node, is_err); 6187 } 6188 6189 IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrOk"); 6190 IrBasicBlock *err_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrError"); 6191 IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "UnwrapErrEnd"); 6192 ir_build_cond_br(irb, parent_scope, node, is_err, err_block, ok_block, is_comptime); 6193 6194 ir_set_cursor_at_end_and_append_block(irb, err_block); 6195 Scope *err_scope; 6196 if (var_node) { 6197 assert(var_node->type == NodeTypeSymbol); 6198 Buf *var_name = var_node->data.symbol_expr.symbol; 6199 bool is_const = true; 6200 bool is_shadowable = false; 6201 ZigVar *var = ir_create_var(irb, node, parent_scope, var_name, 6202 is_const, is_const, is_shadowable, is_comptime); 6203 err_scope = var->child_scope; 6204 IrInstruction *err_val = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); 6205 ir_build_var_decl(irb, err_scope, var_node, var, nullptr, nullptr, err_val); 6206 } else { 6207 err_scope = parent_scope; 6208 } 6209 IrInstruction *err_result = ir_gen_node(irb, op2_node, err_scope); 6210 if (err_result == irb->codegen->invalid_instruction) 6211 return irb->codegen->invalid_instruction; 6212 IrBasicBlock *after_err_block = irb->current_basic_block; 6213 if (!instr_is_unreachable(err_result)) 6214 ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime)); 6215 6216 ir_set_cursor_at_end_and_append_block(irb, ok_block); 6217 IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false); 6218 IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); 6219 IrBasicBlock *after_ok_block = irb->current_basic_block; 6220 ir_build_br(irb, parent_scope, node, end_block, is_comptime); 6221 6222 ir_set_cursor_at_end_and_append_block(irb, end_block); 6223 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 6224 incoming_values[0] = err_result; 6225 incoming_values[1] = unwrapped_payload; 6226 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 6227 incoming_blocks[0] = after_err_block; 6228 incoming_blocks[1] = after_ok_block; 6229 return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); 6230 } 6231 6232 static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *outer_scope, Scope *inner_scope) { 6233 if (inner_scope == nullptr || inner_scope == outer_scope) return false; 6234 bool need_comma = render_instance_name_recursive(codegen, name, outer_scope, inner_scope->parent); 6235 if (inner_scope->id != ScopeIdVarDecl) 6236 return need_comma; 6237 6238 ScopeVarDecl *var_scope = (ScopeVarDecl *)inner_scope; 6239 if (need_comma) 6240 buf_append_char(name, ','); 6241 render_const_value(codegen, name, var_scope->var->value); 6242 return true; 6243 } 6244 6245 static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, AstNode *source_node) { 6246 if (exec->name) { 6247 return exec->name; 6248 } else if (exec->name_fn != nullptr) { 6249 Buf *name = buf_alloc(); 6250 buf_append_buf(name, &exec->name_fn->symbol_name); 6251 buf_appendf(name, "("); 6252 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope); 6253 buf_appendf(name, ")"); 6254 return name; 6255 } else { 6256 //Note: C-imports do not have valid location information 6257 return buf_sprintf("(anonymous %s at %s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ")", kind_name, 6258 (source_node->owner->path != nullptr) ? buf_ptr(source_node->owner->path) : "(null)", source_node->line + 1, source_node->column + 1); 6259 } 6260 } 6261 6262 static IrInstruction *ir_gen_container_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6263 assert(node->type == NodeTypeContainerDecl); 6264 6265 ContainerKind kind = node->data.container_decl.kind; 6266 Buf *name = get_anon_type_name(irb->codegen, irb->exec, container_string(kind), node); 6267 6268 VisibMod visib_mod = VisibModPub; 6269 TldContainer *tld_container = allocate<TldContainer>(1); 6270 init_tld(&tld_container->base, TldIdContainer, name, visib_mod, node, parent_scope); 6271 6272 ContainerLayout layout = node->data.container_decl.layout; 6273 ZigType *container_type = get_partial_container_type(irb->codegen, parent_scope, 6274 kind, node, buf_ptr(name), layout); 6275 ScopeDecls *child_scope = get_container_scope(container_type); 6276 6277 tld_container->type_entry = container_type; 6278 tld_container->decls_scope = child_scope; 6279 6280 for (size_t i = 0; i < node->data.container_decl.decls.length; i += 1) { 6281 AstNode *child_node = node->data.container_decl.decls.at(i); 6282 scan_decls(irb->codegen, child_scope, child_node); 6283 } 6284 irb->codegen->resolve_queue.append(&tld_container->base); 6285 6286 // Add this to the list to mark as invalid if analyzing this exec fails. 6287 irb->exec->tld_list.append(&tld_container->base); 6288 6289 return ir_build_const_type(irb, parent_scope, node, container_type); 6290 } 6291 6292 // errors should be populated with set1's values 6293 static ZigType *get_error_set_union(CodeGen *g, ErrorTableEntry **errors, ZigType *set1, ZigType *set2) { 6294 assert(set1->id == ZigTypeIdErrorSet); 6295 assert(set2->id == ZigTypeIdErrorSet); 6296 6297 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 6298 buf_resize(&err_set_type->name, 0); 6299 buf_appendf(&err_set_type->name, "error.{"); 6300 6301 for (uint32_t i = 0, count = set1->data.error_set.err_count; i < count; i += 1) { 6302 assert(errors[set1->data.error_set.errors[i]->value] == set1->data.error_set.errors[i]); 6303 } 6304 6305 uint32_t count = set1->data.error_set.err_count; 6306 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 6307 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 6308 if (errors[error_entry->value] == nullptr) { 6309 count += 1; 6310 } 6311 } 6312 6313 err_set_type->type_ref = g->builtin_types.entry_global_error_set->type_ref; 6314 err_set_type->di_type = g->builtin_types.entry_global_error_set->di_type; 6315 err_set_type->data.error_set.err_count = count; 6316 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(count); 6317 6318 for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { 6319 ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; 6320 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 6321 err_set_type->data.error_set.errors[i] = error_entry; 6322 } 6323 6324 uint32_t index = set1->data.error_set.err_count; 6325 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 6326 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 6327 if (errors[error_entry->value] == nullptr) { 6328 errors[error_entry->value] = error_entry; 6329 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&error_entry->name)); 6330 err_set_type->data.error_set.errors[index] = error_entry; 6331 index += 1; 6332 } 6333 } 6334 assert(index == count); 6335 assert(count != 0); 6336 6337 buf_appendf(&err_set_type->name, "}"); 6338 6339 g->error_di_types.append(&err_set_type->di_type); 6340 6341 return err_set_type; 6342 6343 } 6344 6345 static ZigType *make_err_set_with_one_item(CodeGen *g, Scope *parent_scope, AstNode *node, 6346 ErrorTableEntry *err_entry) 6347 { 6348 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 6349 buf_resize(&err_set_type->name, 0); 6350 buf_appendf(&err_set_type->name, "error.{%s}", buf_ptr(&err_entry->name)); 6351 err_set_type->type_ref = g->builtin_types.entry_global_error_set->type_ref; 6352 err_set_type->di_type = g->builtin_types.entry_global_error_set->di_type; 6353 err_set_type->data.error_set.err_count = 1; 6354 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1); 6355 6356 g->error_di_types.append(&err_set_type->di_type); 6357 6358 err_set_type->data.error_set.errors[0] = err_entry; 6359 6360 return err_set_type; 6361 } 6362 6363 static IrInstruction *ir_gen_err_set_decl(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6364 assert(node->type == NodeTypeErrorSetDecl); 6365 6366 uint32_t err_count = node->data.err_set_decl.decls.length; 6367 6368 Buf *type_name = get_anon_type_name(irb->codegen, irb->exec, "error set", node); 6369 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 6370 buf_init_from_buf(&err_set_type->name, type_name); 6371 err_set_type->data.error_set.err_count = err_count; 6372 err_set_type->type_ref = irb->codegen->builtin_types.entry_global_error_set->type_ref; 6373 err_set_type->di_type = irb->codegen->builtin_types.entry_global_error_set->di_type; 6374 irb->codegen->error_di_types.append(&err_set_type->di_type); 6375 err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(err_count); 6376 6377 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(irb->codegen->errors_by_index.length + err_count); 6378 6379 for (uint32_t i = 0; i < err_count; i += 1) { 6380 AstNode *symbol_node = node->data.err_set_decl.decls.at(i); 6381 assert(symbol_node->type == NodeTypeSymbol); 6382 Buf *err_name = symbol_node->data.symbol_expr.symbol; 6383 ErrorTableEntry *err = allocate<ErrorTableEntry>(1); 6384 err->decl_node = symbol_node; 6385 buf_init_from_buf(&err->name, err_name); 6386 6387 auto existing_entry = irb->codegen->error_table.put_unique(err_name, err); 6388 if (existing_entry) { 6389 err->value = existing_entry->value->value; 6390 } else { 6391 size_t error_value_count = irb->codegen->errors_by_index.length; 6392 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)irb->codegen->err_tag_type->data.integral.bit_count)); 6393 err->value = error_value_count; 6394 irb->codegen->errors_by_index.append(err); 6395 irb->codegen->err_enumerators.append(ZigLLVMCreateDebugEnumerator(irb->codegen->dbuilder, 6396 buf_ptr(err_name), error_value_count)); 6397 } 6398 err_set_type->data.error_set.errors[i] = err; 6399 6400 ErrorTableEntry *prev_err = errors[err->value]; 6401 if (prev_err != nullptr) { 6402 ErrorMsg *msg = add_node_error(irb->codegen, err->decl_node, buf_sprintf("duplicate error: '%s'", buf_ptr(&err->name))); 6403 add_error_note(irb->codegen, msg, prev_err->decl_node, buf_sprintf("other error here")); 6404 return irb->codegen->invalid_instruction; 6405 } 6406 errors[err->value] = err; 6407 } 6408 free(errors); 6409 return ir_build_const_type(irb, parent_scope, node, err_set_type); 6410 } 6411 6412 static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6413 assert(node->type == NodeTypeFnProto); 6414 6415 size_t param_count = node->data.fn_proto.params.length; 6416 IrInstruction **param_types = allocate<IrInstruction*>(param_count); 6417 6418 bool is_var_args = false; 6419 for (size_t i = 0; i < param_count; i += 1) { 6420 AstNode *param_node = node->data.fn_proto.params.at(i); 6421 if (param_node->data.param_decl.is_var_args) { 6422 is_var_args = true; 6423 break; 6424 } 6425 if (param_node->data.param_decl.var_token == nullptr) { 6426 AstNode *type_node = param_node->data.param_decl.type; 6427 IrInstruction *type_value = ir_gen_node(irb, type_node, parent_scope); 6428 if (type_value == irb->codegen->invalid_instruction) 6429 return irb->codegen->invalid_instruction; 6430 param_types[i] = type_value; 6431 } else { 6432 param_types[i] = nullptr; 6433 } 6434 } 6435 6436 IrInstruction *align_value = nullptr; 6437 if (node->data.fn_proto.align_expr != nullptr) { 6438 align_value = ir_gen_node(irb, node->data.fn_proto.align_expr, parent_scope); 6439 if (align_value == irb->codegen->invalid_instruction) 6440 return irb->codegen->invalid_instruction; 6441 } 6442 6443 IrInstruction *return_type; 6444 if (node->data.fn_proto.return_var_token == nullptr) { 6445 if (node->data.fn_proto.return_type == nullptr) { 6446 return_type = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_void); 6447 } else { 6448 return_type = ir_gen_node(irb, node->data.fn_proto.return_type, parent_scope); 6449 if (return_type == irb->codegen->invalid_instruction) 6450 return irb->codegen->invalid_instruction; 6451 } 6452 } else { 6453 add_node_error(irb->codegen, node, 6454 buf_sprintf("TODO implement inferred return types https://github.com/ziglang/zig/issues/447")); 6455 return irb->codegen->invalid_instruction; 6456 //return_type = nullptr; 6457 } 6458 6459 IrInstruction *async_allocator_type_value = nullptr; 6460 if (node->data.fn_proto.async_allocator_type != nullptr) { 6461 async_allocator_type_value = ir_gen_node(irb, node->data.fn_proto.async_allocator_type, parent_scope); 6462 if (async_allocator_type_value == irb->codegen->invalid_instruction) 6463 return irb->codegen->invalid_instruction; 6464 } 6465 6466 return ir_build_fn_proto(irb, parent_scope, node, param_types, align_value, return_type, 6467 async_allocator_type_value, is_var_args); 6468 } 6469 6470 static IrInstruction *ir_gen_cancel_target(IrBuilder *irb, Scope *scope, AstNode *node, 6471 IrInstruction *target_inst, bool cancel_non_suspended, bool cancel_awaited) 6472 { 6473 IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "CancelDone"); 6474 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); 6475 IrBasicBlock *pre_return_block = ir_create_basic_block(irb, scope, "PreReturn"); 6476 IrBasicBlock *post_return_block = ir_create_basic_block(irb, scope, "PostReturn"); 6477 IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel"); 6478 6479 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 6480 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 6481 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); 6482 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 6483 IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node, 6484 get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void)); 6485 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 6486 IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 6487 IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100 6488 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 6489 6490 // TODO relies on Zig not re-ordering fields 6491 IrInstruction *casted_target_inst = ir_build_ptr_cast(irb, scope, node, promise_T_type_val, target_inst); 6492 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); 6493 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 6494 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 6495 atomic_state_field_name); 6496 6497 // set the is_canceled bit 6498 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 6499 usize_type_val, atomic_state_ptr, nullptr, is_canceled_mask, nullptr, 6500 AtomicRmwOp_or, AtomicOrderSeqCst); 6501 6502 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 6503 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 6504 ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime); 6505 6506 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 6507 IrInstruction *awaiter_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 6508 IrInstruction *is_returned_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, awaiter_addr, ptr_mask, false); 6509 ir_build_cond_br(irb, scope, node, is_returned_bool, post_return_block, pre_return_block, is_comptime); 6510 6511 ir_set_cursor_at_end_and_append_block(irb, post_return_block); 6512 if (cancel_awaited) { 6513 ir_build_br(irb, scope, node, do_cancel_block, is_comptime); 6514 } else { 6515 IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false); 6516 IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false); 6517 ir_build_cond_br(irb, scope, node, is_awaited_bool, done_block, do_cancel_block, is_comptime); 6518 } 6519 6520 ir_set_cursor_at_end_and_append_block(irb, pre_return_block); 6521 if (cancel_awaited) { 6522 if (cancel_non_suspended) { 6523 ir_build_br(irb, scope, node, do_cancel_block, is_comptime); 6524 } else { 6525 IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 6526 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 6527 ir_build_cond_br(irb, scope, node, is_suspended_bool, do_cancel_block, done_block, is_comptime); 6528 } 6529 } else { 6530 ir_build_br(irb, scope, node, done_block, is_comptime); 6531 } 6532 6533 ir_set_cursor_at_end_and_append_block(irb, do_cancel_block); 6534 ir_build_cancel(irb, scope, node, target_inst); 6535 ir_build_br(irb, scope, node, done_block, is_comptime); 6536 6537 ir_set_cursor_at_end_and_append_block(irb, done_block); 6538 return ir_build_const_void(irb, scope, node); 6539 } 6540 6541 static IrInstruction *ir_gen_cancel(IrBuilder *irb, Scope *scope, AstNode *node) { 6542 assert(node->type == NodeTypeCancel); 6543 6544 IrInstruction *target_inst = ir_gen_node(irb, node->data.cancel_expr.expr, scope); 6545 if (target_inst == irb->codegen->invalid_instruction) 6546 return irb->codegen->invalid_instruction; 6547 6548 return ir_gen_cancel_target(irb, scope, node, target_inst, false, true); 6549 } 6550 6551 static IrInstruction *ir_gen_resume_target(IrBuilder *irb, Scope *scope, AstNode *node, 6552 IrInstruction *target_inst) 6553 { 6554 IrBasicBlock *done_block = ir_create_basic_block(irb, scope, "ResumeDone"); 6555 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); 6556 IrBasicBlock *suspended_block = ir_create_basic_block(irb, scope, "IsSuspended"); 6557 IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, scope, "IsNotSuspended"); 6558 6559 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 6560 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 6561 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 6562 IrInstruction *and_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, is_suspended_mask); 6563 IrInstruction *is_comptime = ir_build_const_bool(irb, scope, node, false); 6564 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 6565 IrInstruction *promise_T_type_val = ir_build_const_type(irb, scope, node, 6566 get_promise_type(irb->codegen, irb->codegen->builtin_types.entry_void)); 6567 6568 // TODO relies on Zig not re-ordering fields 6569 IrInstruction *casted_target_inst = ir_build_ptr_cast(irb, scope, node, promise_T_type_val, target_inst); 6570 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, casted_target_inst); 6571 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 6572 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 6573 atomic_state_field_name); 6574 6575 // clear the is_suspended bit 6576 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 6577 usize_type_val, atomic_state_ptr, nullptr, and_mask, nullptr, 6578 AtomicRmwOp_and, AtomicOrderSeqCst); 6579 6580 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 6581 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 6582 ir_build_cond_br(irb, scope, node, is_canceled_bool, done_block, not_canceled_block, is_comptime); 6583 6584 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 6585 IrInstruction *is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 6586 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 6587 ir_build_cond_br(irb, scope, node, is_suspended_bool, suspended_block, not_suspended_block, is_comptime); 6588 6589 ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); 6590 ir_build_unreachable(irb, scope, node); 6591 6592 ir_set_cursor_at_end_and_append_block(irb, suspended_block); 6593 ir_build_coro_resume(irb, scope, node, target_inst); 6594 ir_build_br(irb, scope, node, done_block, is_comptime); 6595 6596 ir_set_cursor_at_end_and_append_block(irb, done_block); 6597 return ir_build_const_void(irb, scope, node); 6598 } 6599 6600 static IrInstruction *ir_gen_resume(IrBuilder *irb, Scope *scope, AstNode *node) { 6601 assert(node->type == NodeTypeResume); 6602 6603 IrInstruction *target_inst = ir_gen_node(irb, node->data.resume_expr.expr, scope); 6604 if (target_inst == irb->codegen->invalid_instruction) 6605 return irb->codegen->invalid_instruction; 6606 6607 return ir_gen_resume_target(irb, scope, node, target_inst); 6608 } 6609 6610 static IrInstruction *ir_gen_await_expr(IrBuilder *irb, Scope *scope, AstNode *node) { 6611 assert(node->type == NodeTypeAwaitExpr); 6612 6613 IrInstruction *target_inst = ir_gen_node(irb, node->data.await_expr.expr, scope); 6614 if (target_inst == irb->codegen->invalid_instruction) 6615 return irb->codegen->invalid_instruction; 6616 6617 ZigFn *fn_entry = exec_fn_entry(irb->exec); 6618 if (!fn_entry) { 6619 add_node_error(irb->codegen, node, buf_sprintf("await outside function definition")); 6620 return irb->codegen->invalid_instruction; 6621 } 6622 if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) { 6623 add_node_error(irb->codegen, node, buf_sprintf("await in non-async function")); 6624 return irb->codegen->invalid_instruction; 6625 } 6626 6627 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(scope); 6628 if (scope_defer_expr) { 6629 if (!scope_defer_expr->reported_err) { 6630 add_node_error(irb->codegen, node, buf_sprintf("cannot await inside defer expression")); 6631 scope_defer_expr->reported_err = true; 6632 } 6633 return irb->codegen->invalid_instruction; 6634 } 6635 6636 Scope *outer_scope = irb->exec->begin_scope; 6637 6638 IrInstruction *coro_promise_ptr = ir_build_coro_promise(irb, scope, node, target_inst); 6639 Buf *result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); 6640 IrInstruction *result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); 6641 6642 if (irb->codegen->have_err_ret_tracing) { 6643 IrInstruction *err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); 6644 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); 6645 IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); 6646 ir_build_store_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr, err_ret_trace_ptr); 6647 } 6648 6649 IrBasicBlock *already_awaited_block = ir_create_basic_block(irb, scope, "AlreadyAwaited"); 6650 IrBasicBlock *not_awaited_block = ir_create_basic_block(irb, scope, "NotAwaited"); 6651 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, scope, "NotCanceled"); 6652 IrBasicBlock *yes_suspend_block = ir_create_basic_block(irb, scope, "YesSuspend"); 6653 IrBasicBlock *no_suspend_block = ir_create_basic_block(irb, scope, "NoSuspend"); 6654 IrBasicBlock *merge_block = ir_create_basic_block(irb, scope, "MergeSuspend"); 6655 IrBasicBlock *cleanup_block = ir_create_basic_block(irb, scope, "SuspendCleanup"); 6656 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "SuspendResume"); 6657 IrBasicBlock *cancel_target_block = ir_create_basic_block(irb, scope, "CancelTarget"); 6658 IrBasicBlock *do_cancel_block = ir_create_basic_block(irb, scope, "DoCancel"); 6659 IrBasicBlock *do_defers_block = ir_create_basic_block(irb, scope, "DoDefers"); 6660 IrBasicBlock *destroy_block = ir_create_basic_block(irb, scope, "DestroyBlock"); 6661 IrBasicBlock *my_suspended_block = ir_create_basic_block(irb, scope, "AlreadySuspended"); 6662 IrBasicBlock *my_not_suspended_block = ir_create_basic_block(irb, scope, "NotAlreadySuspended"); 6663 IrBasicBlock *do_suspend_block = ir_create_basic_block(irb, scope, "DoSuspend"); 6664 6665 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 6666 IrInstruction *atomic_state_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 6667 atomic_state_field_name); 6668 6669 IrInstruction *promise_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_promise); 6670 IrInstruction *const_bool_false = ir_build_const_bool(irb, scope, node, false); 6671 IrInstruction *undefined_value = ir_build_const_undefined(irb, scope, node); 6672 IrInstruction *usize_type_val = ir_build_const_type(irb, scope, node, irb->codegen->builtin_types.entry_usize); 6673 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 6674 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, scope, node, 0x7); // 0b111 6675 IrInstruction *ptr_mask = ir_build_un_op(irb, scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 6676 IrInstruction *await_mask = ir_build_const_usize(irb, scope, node, 0x4); // 0b100 6677 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, scope, node, 0x1); // 0b001 6678 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, scope, node, 0x2); // 0b010 6679 6680 ZigVar *result_var = ir_create_var(irb, node, scope, nullptr, 6681 false, false, true, const_bool_false); 6682 IrInstruction *target_promise_type = ir_build_typeof(irb, scope, node, target_inst); 6683 IrInstruction *promise_result_type = ir_build_promise_result_type(irb, scope, node, target_promise_type); 6684 ir_build_await_bookkeeping(irb, scope, node, promise_result_type); 6685 ir_build_var_decl(irb, scope, node, result_var, promise_result_type, nullptr, undefined_value); 6686 IrInstruction *my_result_var_ptr = ir_build_var_ptr(irb, scope, node, result_var); 6687 ir_build_store_ptr(irb, scope, node, result_ptr_field_ptr, my_result_var_ptr); 6688 IrInstruction *save_token = ir_build_coro_save(irb, scope, node, irb->exec->coro_handle); 6689 6690 IrInstruction *coro_handle_addr = ir_build_ptr_to_int(irb, scope, node, irb->exec->coro_handle); 6691 IrInstruction *mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, coro_handle_addr, await_mask, false); 6692 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 6693 usize_type_val, atomic_state_ptr, nullptr, mask_bits, nullptr, 6694 AtomicRmwOp_or, AtomicOrderSeqCst); 6695 6696 IrInstruction *is_awaited_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, await_mask, false); 6697 IrInstruction *is_awaited_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_awaited_value, zero, false); 6698 ir_build_cond_br(irb, scope, node, is_awaited_bool, already_awaited_block, not_awaited_block, const_bool_false); 6699 6700 ir_set_cursor_at_end_and_append_block(irb, already_awaited_block); 6701 ir_build_unreachable(irb, scope, node); 6702 6703 ir_set_cursor_at_end_and_append_block(irb, not_awaited_block); 6704 IrInstruction *await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 6705 IrInstruction *is_non_null = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); 6706 IrInstruction *is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 6707 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 6708 ir_build_cond_br(irb, scope, node, is_canceled_bool, cancel_target_block, not_canceled_block, const_bool_false); 6709 6710 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 6711 ir_build_cond_br(irb, scope, node, is_non_null, no_suspend_block, yes_suspend_block, const_bool_false); 6712 6713 ir_set_cursor_at_end_and_append_block(irb, cancel_target_block); 6714 ir_build_cancel(irb, scope, node, target_inst); 6715 ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false)); 6716 6717 ir_set_cursor_at_end_and_append_block(irb, no_suspend_block); 6718 if (irb->codegen->have_err_ret_tracing) { 6719 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); 6720 IrInstruction *src_err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); 6721 IrInstruction *dest_err_ret_trace_ptr = ir_build_error_return_trace(irb, scope, node, IrInstructionErrorReturnTrace::NonNull); 6722 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); 6723 } 6724 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); 6725 IrInstruction *promise_result_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); 6726 // If the type of the result handle_is_ptr then this does not actually perform a load. But we need it to, 6727 // because we're about to destroy the memory. So we store it into our result variable. 6728 IrInstruction *no_suspend_result = ir_build_load_ptr(irb, scope, node, promise_result_ptr); 6729 ir_build_store_ptr(irb, scope, node, my_result_var_ptr, no_suspend_result); 6730 ir_build_cancel(irb, scope, node, target_inst); 6731 ir_build_br(irb, scope, node, merge_block, const_bool_false); 6732 6733 6734 ir_set_cursor_at_end_and_append_block(irb, yes_suspend_block); 6735 IrInstruction *my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 6736 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr, 6737 AtomicRmwOp_or, AtomicOrderSeqCst); 6738 IrInstruction *my_is_suspended_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_suspended_mask, false); 6739 IrInstruction *my_is_suspended_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_suspended_value, zero, false); 6740 ir_build_cond_br(irb, scope, node, my_is_suspended_bool, my_suspended_block, my_not_suspended_block, const_bool_false); 6741 6742 ir_set_cursor_at_end_and_append_block(irb, my_suspended_block); 6743 ir_build_unreachable(irb, scope, node); 6744 6745 ir_set_cursor_at_end_and_append_block(irb, my_not_suspended_block); 6746 IrInstruction *my_is_canceled_value = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, my_prev_atomic_value, is_canceled_mask, false); 6747 IrInstruction *my_is_canceled_bool = ir_build_bin_op(irb, scope, node, IrBinOpCmpNotEq, my_is_canceled_value, zero, false); 6748 ir_build_cond_br(irb, scope, node, my_is_canceled_bool, cleanup_block, do_suspend_block, const_bool_false); 6749 6750 ir_set_cursor_at_end_and_append_block(irb, do_suspend_block); 6751 IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, save_token, const_bool_false); 6752 6753 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); 6754 cases[0].value = ir_build_const_u8(irb, scope, node, 0); 6755 cases[0].block = resume_block; 6756 cases[1].value = ir_build_const_u8(irb, scope, node, 1); 6757 cases[1].block = destroy_block; 6758 ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 6759 2, cases, const_bool_false, nullptr); 6760 6761 ir_set_cursor_at_end_and_append_block(irb, destroy_block); 6762 ir_gen_cancel_target(irb, scope, node, target_inst, false, true); 6763 ir_mark_gen(ir_build_br(irb, scope, node, cleanup_block, const_bool_false)); 6764 6765 ir_set_cursor_at_end_and_append_block(irb, cleanup_block); 6766 IrInstruction *my_mask_bits = ir_build_bin_op(irb, scope, node, IrBinOpBinOr, ptr_mask, is_canceled_mask, false); 6767 IrInstruction *b_my_prev_atomic_value = ir_build_atomic_rmw(irb, scope, node, 6768 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, my_mask_bits, nullptr, 6769 AtomicRmwOp_or, AtomicOrderSeqCst); 6770 IrInstruction *my_await_handle_addr = ir_build_bin_op(irb, scope, node, IrBinOpBinAnd, b_my_prev_atomic_value, ptr_mask, false); 6771 IrInstruction *dont_have_my_await_handle = ir_build_bin_op(irb, scope, node, IrBinOpCmpEq, my_await_handle_addr, zero, false); 6772 IrInstruction *dont_destroy_ourselves = ir_build_bin_op(irb, scope, node, IrBinOpBoolAnd, dont_have_my_await_handle, is_canceled_bool, false); 6773 ir_build_cond_br(irb, scope, node, dont_have_my_await_handle, do_defers_block, do_cancel_block, const_bool_false); 6774 6775 ir_set_cursor_at_end_and_append_block(irb, do_cancel_block); 6776 IrInstruction *my_await_handle = ir_build_int_to_ptr(irb, scope, node, promise_type_val, my_await_handle_addr); 6777 ir_gen_cancel_target(irb, scope, node, my_await_handle, true, false); 6778 ir_mark_gen(ir_build_br(irb, scope, node, do_defers_block, const_bool_false)); 6779 6780 ir_set_cursor_at_end_and_append_block(irb, do_defers_block); 6781 ir_gen_defers_for_block(irb, scope, outer_scope, true); 6782 ir_mark_gen(ir_build_cond_br(irb, scope, node, dont_destroy_ourselves, irb->exec->coro_early_final, irb->exec->coro_final_cleanup_block, const_bool_false)); 6783 6784 ir_set_cursor_at_end_and_append_block(irb, resume_block); 6785 ir_build_br(irb, scope, node, merge_block, const_bool_false); 6786 6787 ir_set_cursor_at_end_and_append_block(irb, merge_block); 6788 return ir_build_load_ptr(irb, scope, node, my_result_var_ptr); 6789 } 6790 6791 static IrInstruction *ir_gen_suspend(IrBuilder *irb, Scope *parent_scope, AstNode *node) { 6792 assert(node->type == NodeTypeSuspend); 6793 6794 ZigFn *fn_entry = exec_fn_entry(irb->exec); 6795 if (!fn_entry) { 6796 add_node_error(irb->codegen, node, buf_sprintf("suspend outside function definition")); 6797 return irb->codegen->invalid_instruction; 6798 } 6799 if (fn_entry->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync) { 6800 add_node_error(irb->codegen, node, buf_sprintf("suspend in non-async function")); 6801 return irb->codegen->invalid_instruction; 6802 } 6803 6804 ScopeDeferExpr *scope_defer_expr = get_scope_defer_expr(parent_scope); 6805 if (scope_defer_expr) { 6806 if (!scope_defer_expr->reported_err) { 6807 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside defer expression")); 6808 add_error_note(irb->codegen, msg, scope_defer_expr->base.source_node, buf_sprintf("defer here")); 6809 scope_defer_expr->reported_err = true; 6810 } 6811 return irb->codegen->invalid_instruction; 6812 } 6813 ScopeSuspend *existing_suspend_scope = get_scope_suspend(parent_scope); 6814 if (existing_suspend_scope) { 6815 if (!existing_suspend_scope->reported_err) { 6816 ErrorMsg *msg = add_node_error(irb->codegen, node, buf_sprintf("cannot suspend inside suspend block")); 6817 add_error_note(irb->codegen, msg, existing_suspend_scope->base.source_node, buf_sprintf("other suspend block here")); 6818 existing_suspend_scope->reported_err = true; 6819 } 6820 return irb->codegen->invalid_instruction; 6821 } 6822 6823 Scope *outer_scope = irb->exec->begin_scope; 6824 6825 IrBasicBlock *cleanup_block = ir_create_basic_block(irb, parent_scope, "SuspendCleanup"); 6826 IrBasicBlock *resume_block = ir_create_basic_block(irb, parent_scope, "SuspendResume"); 6827 IrBasicBlock *suspended_block = ir_create_basic_block(irb, parent_scope, "AlreadySuspended"); 6828 IrBasicBlock *canceled_block = ir_create_basic_block(irb, parent_scope, "IsCanceled"); 6829 IrBasicBlock *not_canceled_block = ir_create_basic_block(irb, parent_scope, "NotCanceled"); 6830 IrBasicBlock *not_suspended_block = ir_create_basic_block(irb, parent_scope, "NotAlreadySuspended"); 6831 IrBasicBlock *cancel_awaiter_block = ir_create_basic_block(irb, parent_scope, "CancelAwaiter"); 6832 6833 IrInstruction *promise_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_promise); 6834 IrInstruction *const_bool_true = ir_build_const_bool(irb, parent_scope, node, true); 6835 IrInstruction *const_bool_false = ir_build_const_bool(irb, parent_scope, node, false); 6836 IrInstruction *usize_type_val = ir_build_const_type(irb, parent_scope, node, irb->codegen->builtin_types.entry_usize); 6837 IrInstruction *is_canceled_mask = ir_build_const_usize(irb, parent_scope, node, 0x1); // 0b001 6838 IrInstruction *is_suspended_mask = ir_build_const_usize(irb, parent_scope, node, 0x2); // 0b010 6839 IrInstruction *zero = ir_build_const_usize(irb, parent_scope, node, 0); 6840 IrInstruction *inverted_ptr_mask = ir_build_const_usize(irb, parent_scope, node, 0x7); // 0b111 6841 IrInstruction *ptr_mask = ir_build_un_op(irb, parent_scope, node, IrUnOpBinNot, inverted_ptr_mask); // 0b111...000 6842 6843 IrInstruction *prev_atomic_value = ir_build_atomic_rmw(irb, parent_scope, node, 6844 usize_type_val, irb->exec->atomic_state_field_ptr, nullptr, is_suspended_mask, nullptr, 6845 AtomicRmwOp_or, AtomicOrderSeqCst); 6846 6847 IrInstruction *is_canceled_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_canceled_mask, false); 6848 IrInstruction *is_canceled_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_canceled_value, zero, false); 6849 ir_build_cond_br(irb, parent_scope, node, is_canceled_bool, canceled_block, not_canceled_block, const_bool_false); 6850 6851 ir_set_cursor_at_end_and_append_block(irb, canceled_block); 6852 IrInstruction *await_handle_addr = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, ptr_mask, false); 6853 IrInstruction *have_await_handle = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, await_handle_addr, zero, false); 6854 IrBasicBlock *post_canceled_block = irb->current_basic_block; 6855 ir_build_cond_br(irb, parent_scope, node, have_await_handle, cancel_awaiter_block, cleanup_block, const_bool_false); 6856 6857 ir_set_cursor_at_end_and_append_block(irb, cancel_awaiter_block); 6858 IrInstruction *await_handle = ir_build_int_to_ptr(irb, parent_scope, node, promise_type_val, await_handle_addr); 6859 ir_gen_cancel_target(irb, parent_scope, node, await_handle, true, false); 6860 IrBasicBlock *post_cancel_awaiter_block = irb->current_basic_block; 6861 ir_build_br(irb, parent_scope, node, cleanup_block, const_bool_false); 6862 6863 ir_set_cursor_at_end_and_append_block(irb, not_canceled_block); 6864 IrInstruction *is_suspended_value = ir_build_bin_op(irb, parent_scope, node, IrBinOpBinAnd, prev_atomic_value, is_suspended_mask, false); 6865 IrInstruction *is_suspended_bool = ir_build_bin_op(irb, parent_scope, node, IrBinOpCmpNotEq, is_suspended_value, zero, false); 6866 ir_build_cond_br(irb, parent_scope, node, is_suspended_bool, suspended_block, not_suspended_block, const_bool_false); 6867 6868 ir_set_cursor_at_end_and_append_block(irb, suspended_block); 6869 ir_build_unreachable(irb, parent_scope, node); 6870 6871 ir_set_cursor_at_end_and_append_block(irb, not_suspended_block); 6872 IrInstruction *suspend_code; 6873 if (node->data.suspend.block == nullptr) { 6874 suspend_code = ir_build_coro_suspend(irb, parent_scope, node, nullptr, const_bool_false); 6875 } else { 6876 Scope *child_scope; 6877 ScopeSuspend *suspend_scope = create_suspend_scope(irb->codegen, node, parent_scope); 6878 suspend_scope->resume_block = resume_block; 6879 child_scope = &suspend_scope->base; 6880 IrInstruction *save_token = ir_build_coro_save(irb, child_scope, node, irb->exec->coro_handle); 6881 ir_gen_node(irb, node->data.suspend.block, child_scope); 6882 suspend_code = ir_mark_gen(ir_build_coro_suspend(irb, parent_scope, node, save_token, const_bool_false)); 6883 } 6884 6885 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); 6886 cases[0].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 0)); 6887 cases[0].block = resume_block; 6888 cases[1].value = ir_mark_gen(ir_build_const_u8(irb, parent_scope, node, 1)); 6889 cases[1].block = canceled_block; 6890 ir_mark_gen(ir_build_switch_br(irb, parent_scope, node, suspend_code, irb->exec->coro_suspend_block, 6891 2, cases, const_bool_false, nullptr)); 6892 6893 ir_set_cursor_at_end_and_append_block(irb, cleanup_block); 6894 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 6895 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 6896 incoming_blocks[0] = post_canceled_block; 6897 incoming_values[0] = const_bool_true; 6898 incoming_blocks[1] = post_cancel_awaiter_block; 6899 incoming_values[1] = const_bool_false; 6900 IrInstruction *destroy_ourselves = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); 6901 ir_gen_defers_for_block(irb, parent_scope, outer_scope, true); 6902 ir_mark_gen(ir_build_cond_br(irb, parent_scope, node, destroy_ourselves, irb->exec->coro_final_cleanup_block, irb->exec->coro_early_final, const_bool_false)); 6903 6904 ir_set_cursor_at_end_and_append_block(irb, resume_block); 6905 return ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); 6906 } 6907 6908 static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, 6909 LVal lval) 6910 { 6911 assert(scope); 6912 switch (node->type) { 6913 case NodeTypeStructValueField: 6914 case NodeTypeRoot: 6915 case NodeTypeParamDecl: 6916 case NodeTypeUse: 6917 case NodeTypeSwitchProng: 6918 case NodeTypeSwitchRange: 6919 case NodeTypeStructField: 6920 case NodeTypeFnDef: 6921 case NodeTypeTestDecl: 6922 zig_unreachable(); 6923 case NodeTypeBlock: 6924 return ir_lval_wrap(irb, scope, ir_gen_block(irb, scope, node), lval); 6925 case NodeTypeGroupedExpr: 6926 return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval); 6927 case NodeTypeBinOpExpr: 6928 return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval); 6929 case NodeTypeIntLiteral: 6930 return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval); 6931 case NodeTypeFloatLiteral: 6932 return ir_lval_wrap(irb, scope, ir_gen_float_lit(irb, scope, node), lval); 6933 case NodeTypeCharLiteral: 6934 return ir_lval_wrap(irb, scope, ir_gen_char_lit(irb, scope, node), lval); 6935 case NodeTypeSymbol: 6936 return ir_gen_symbol(irb, scope, node, lval); 6937 case NodeTypeFnCallExpr: 6938 return ir_gen_fn_call(irb, scope, node, lval); 6939 case NodeTypeIfBoolExpr: 6940 return ir_lval_wrap(irb, scope, ir_gen_if_bool_expr(irb, scope, node), lval); 6941 case NodeTypePrefixOpExpr: 6942 return ir_gen_prefix_op_expr(irb, scope, node, lval); 6943 case NodeTypeContainerInitExpr: 6944 return ir_lval_wrap(irb, scope, ir_gen_container_init_expr(irb, scope, node), lval); 6945 case NodeTypeVariableDeclaration: 6946 return ir_lval_wrap(irb, scope, ir_gen_var_decl(irb, scope, node), lval); 6947 case NodeTypeWhileExpr: 6948 return ir_lval_wrap(irb, scope, ir_gen_while_expr(irb, scope, node), lval); 6949 case NodeTypeForExpr: 6950 return ir_lval_wrap(irb, scope, ir_gen_for_expr(irb, scope, node), lval); 6951 case NodeTypeArrayAccessExpr: 6952 return ir_gen_array_access(irb, scope, node, lval); 6953 case NodeTypeReturnExpr: 6954 return ir_gen_return(irb, scope, node, lval); 6955 case NodeTypeFieldAccessExpr: 6956 { 6957 IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node); 6958 if (ptr_instruction == irb->codegen->invalid_instruction) 6959 return ptr_instruction; 6960 if (lval == LValPtr) 6961 return ptr_instruction; 6962 6963 return ir_build_load_ptr(irb, scope, node, ptr_instruction); 6964 } 6965 case NodeTypePtrDeref: { 6966 AstNode *expr_node = node->data.ptr_deref_expr.target; 6967 IrInstruction *value = ir_gen_node_extra(irb, expr_node, scope, lval); 6968 if (value == irb->codegen->invalid_instruction) 6969 return value; 6970 6971 return ir_build_un_op(irb, scope, node, IrUnOpDereference, value); 6972 } 6973 case NodeTypeUnwrapOptional: { 6974 AstNode *expr_node = node->data.unwrap_optional.expr; 6975 6976 IrInstruction *maybe_ptr = ir_gen_node_extra(irb, expr_node, scope, LValPtr); 6977 if (maybe_ptr == irb->codegen->invalid_instruction) 6978 return irb->codegen->invalid_instruction; 6979 6980 IrInstruction *unwrapped_ptr = ir_build_unwrap_maybe(irb, scope, node, maybe_ptr, true); 6981 if (lval == LValPtr) 6982 return unwrapped_ptr; 6983 6984 return ir_build_load_ptr(irb, scope, node, unwrapped_ptr); 6985 } 6986 case NodeTypeBoolLiteral: 6987 return ir_lval_wrap(irb, scope, ir_gen_bool_literal(irb, scope, node), lval); 6988 case NodeTypeArrayType: 6989 return ir_lval_wrap(irb, scope, ir_gen_array_type(irb, scope, node), lval); 6990 case NodeTypePointerType: 6991 return ir_lval_wrap(irb, scope, ir_gen_pointer_type(irb, scope, node), lval); 6992 case NodeTypePromiseType: 6993 return ir_lval_wrap(irb, scope, ir_gen_promise_type(irb, scope, node), lval); 6994 case NodeTypeStringLiteral: 6995 return ir_lval_wrap(irb, scope, ir_gen_string_literal(irb, scope, node), lval); 6996 case NodeTypeUndefinedLiteral: 6997 return ir_lval_wrap(irb, scope, ir_gen_undefined_literal(irb, scope, node), lval); 6998 case NodeTypeAsmExpr: 6999 return ir_lval_wrap(irb, scope, ir_gen_asm_expr(irb, scope, node), lval); 7000 case NodeTypeNullLiteral: 7001 return ir_lval_wrap(irb, scope, ir_gen_null_literal(irb, scope, node), lval); 7002 case NodeTypeIfErrorExpr: 7003 return ir_lval_wrap(irb, scope, ir_gen_if_err_expr(irb, scope, node), lval); 7004 case NodeTypeTestExpr: 7005 return ir_lval_wrap(irb, scope, ir_gen_test_expr(irb, scope, node), lval); 7006 case NodeTypeSwitchExpr: 7007 return ir_lval_wrap(irb, scope, ir_gen_switch_expr(irb, scope, node), lval); 7008 case NodeTypeCompTime: 7009 return ir_gen_comptime(irb, scope, node, lval); 7010 case NodeTypeErrorType: 7011 return ir_lval_wrap(irb, scope, ir_gen_error_type(irb, scope, node), lval); 7012 case NodeTypeBreak: 7013 return ir_lval_wrap(irb, scope, ir_gen_break(irb, scope, node), lval); 7014 case NodeTypeContinue: 7015 return ir_lval_wrap(irb, scope, ir_gen_continue(irb, scope, node), lval); 7016 case NodeTypeUnreachable: 7017 return ir_lval_wrap(irb, scope, ir_build_unreachable(irb, scope, node), lval); 7018 case NodeTypeDefer: 7019 return ir_lval_wrap(irb, scope, ir_gen_defer(irb, scope, node), lval); 7020 case NodeTypeSliceExpr: 7021 return ir_lval_wrap(irb, scope, ir_gen_slice(irb, scope, node), lval); 7022 case NodeTypeUnwrapErrorExpr: 7023 return ir_lval_wrap(irb, scope, ir_gen_err_ok_or(irb, scope, node), lval); 7024 case NodeTypeContainerDecl: 7025 return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval); 7026 case NodeTypeFnProto: 7027 return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval); 7028 case NodeTypeErrorSetDecl: 7029 return ir_lval_wrap(irb, scope, ir_gen_err_set_decl(irb, scope, node), lval); 7030 case NodeTypeCancel: 7031 return ir_lval_wrap(irb, scope, ir_gen_cancel(irb, scope, node), lval); 7032 case NodeTypeResume: 7033 return ir_lval_wrap(irb, scope, ir_gen_resume(irb, scope, node), lval); 7034 case NodeTypeAwaitExpr: 7035 return ir_lval_wrap(irb, scope, ir_gen_await_expr(irb, scope, node), lval); 7036 case NodeTypeSuspend: 7037 return ir_lval_wrap(irb, scope, ir_gen_suspend(irb, scope, node), lval); 7038 } 7039 zig_unreachable(); 7040 } 7041 7042 static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval) { 7043 IrInstruction *result = ir_gen_node_raw(irb, node, scope, lval); 7044 irb->exec->invalid = irb->exec->invalid || (result == irb->codegen->invalid_instruction); 7045 return result; 7046 } 7047 7048 static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope) { 7049 return ir_gen_node_extra(irb, node, scope, LValNone); 7050 } 7051 7052 static void invalidate_exec(IrExecutable *exec) { 7053 if (exec->invalid) 7054 return; 7055 7056 exec->invalid = true; 7057 7058 for (size_t i = 0; i < exec->tld_list.length; i += 1) { 7059 exec->tld_list.items[i]->resolution = TldResolutionInvalid; 7060 } 7061 7062 if (exec->source_exec != nullptr) 7063 invalidate_exec(exec->source_exec); 7064 } 7065 7066 7067 bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_executable) { 7068 assert(node->owner); 7069 7070 IrBuilder ir_builder = {0}; 7071 IrBuilder *irb = &ir_builder; 7072 7073 irb->codegen = codegen; 7074 irb->exec = ir_executable; 7075 7076 IrBasicBlock *entry_block = ir_create_basic_block(irb, scope, "Entry"); 7077 ir_set_cursor_at_end_and_append_block(irb, entry_block); 7078 // Entry block gets a reference because we enter it to begin. 7079 ir_ref_bb(irb->current_basic_block); 7080 7081 ZigFn *fn_entry = exec_fn_entry(irb->exec); 7082 bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; 7083 IrInstruction *coro_id; 7084 IrInstruction *u8_ptr_type; 7085 IrInstruction *const_bool_false; 7086 IrInstruction *coro_promise_ptr; 7087 IrInstruction *err_ret_trace_ptr; 7088 ZigType *return_type; 7089 Buf *result_ptr_field_name; 7090 ZigVar *coro_size_var; 7091 if (is_async) { 7092 // create the coro promise 7093 Scope *coro_scope = create_coro_prelude_scope(irb->codegen, node, scope); 7094 const_bool_false = ir_build_const_bool(irb, coro_scope, node, false); 7095 ZigVar *promise_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); 7096 7097 return_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; 7098 IrInstruction *undef = ir_build_const_undefined(irb, coro_scope, node); 7099 ZigType *coro_frame_type = get_promise_frame_type(irb->codegen, return_type); 7100 IrInstruction *coro_frame_type_value = ir_build_const_type(irb, coro_scope, node, coro_frame_type); 7101 // TODO mark this var decl as "no safety" e.g. disable initializing the undef value to 0xaa 7102 ir_build_var_decl(irb, coro_scope, node, promise_var, coro_frame_type_value, nullptr, undef); 7103 coro_promise_ptr = ir_build_var_ptr(irb, coro_scope, node, promise_var); 7104 7105 ZigVar *await_handle_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); 7106 IrInstruction *null_value = ir_build_const_null(irb, coro_scope, node); 7107 IrInstruction *await_handle_type_val = ir_build_const_type(irb, coro_scope, node, 7108 get_optional_type(irb->codegen, irb->codegen->builtin_types.entry_promise)); 7109 ir_build_var_decl(irb, coro_scope, node, await_handle_var, await_handle_type_val, nullptr, null_value); 7110 irb->exec->await_handle_var_ptr = ir_build_var_ptr(irb, coro_scope, node, await_handle_var); 7111 7112 u8_ptr_type = ir_build_const_type(irb, coro_scope, node, 7113 get_pointer_to_type(irb->codegen, irb->codegen->builtin_types.entry_u8, false)); 7114 IrInstruction *promise_as_u8_ptr = ir_build_ptr_cast(irb, coro_scope, node, u8_ptr_type, coro_promise_ptr); 7115 coro_id = ir_build_coro_id(irb, coro_scope, node, promise_as_u8_ptr); 7116 coro_size_var = ir_create_var(irb, node, coro_scope, nullptr, false, false, true, const_bool_false); 7117 IrInstruction *coro_size = ir_build_coro_size(irb, coro_scope, node); 7118 ir_build_var_decl(irb, coro_scope, node, coro_size_var, nullptr, nullptr, coro_size); 7119 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, coro_scope, node, 7120 ImplicitAllocatorIdArg); 7121 irb->exec->coro_allocator_var = ir_create_var(irb, node, coro_scope, nullptr, true, true, true, const_bool_false); 7122 ir_build_var_decl(irb, coro_scope, node, irb->exec->coro_allocator_var, nullptr, nullptr, implicit_allocator_ptr); 7123 Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME); 7124 IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, coro_scope, node, implicit_allocator_ptr, alloc_field_name); 7125 IrInstruction *alloc_fn = ir_build_load_ptr(irb, coro_scope, node, alloc_fn_ptr); 7126 IrInstruction *maybe_coro_mem_ptr = ir_build_coro_alloc_helper(irb, coro_scope, node, alloc_fn, coro_size); 7127 IrInstruction *alloc_result_is_ok = ir_build_test_nonnull(irb, coro_scope, node, maybe_coro_mem_ptr); 7128 IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, coro_scope, "AllocError"); 7129 IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, coro_scope, "AllocOk"); 7130 ir_build_cond_br(irb, coro_scope, node, alloc_result_is_ok, alloc_ok_block, alloc_err_block, const_bool_false); 7131 7132 ir_set_cursor_at_end_and_append_block(irb, alloc_err_block); 7133 // we can return undefined here, because the caller passes a pointer to the error struct field 7134 // in the error union result, and we populate it in case of allocation failure. 7135 ir_build_return(irb, coro_scope, node, undef); 7136 7137 ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block); 7138 IrInstruction *coro_mem_ptr = ir_build_ptr_cast(irb, coro_scope, node, u8_ptr_type, maybe_coro_mem_ptr); 7139 irb->exec->coro_handle = ir_build_coro_begin(irb, coro_scope, node, coro_id, coro_mem_ptr); 7140 7141 Buf *atomic_state_field_name = buf_create_from_str(ATOMIC_STATE_FIELD_NAME); 7142 irb->exec->atomic_state_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, 7143 atomic_state_field_name); 7144 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 7145 ir_build_store_ptr(irb, scope, node, irb->exec->atomic_state_field_ptr, zero); 7146 Buf *result_field_name = buf_create_from_str(RESULT_FIELD_NAME); 7147 irb->exec->coro_result_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_field_name); 7148 result_ptr_field_name = buf_create_from_str(RESULT_PTR_FIELD_NAME); 7149 irb->exec->coro_result_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, result_ptr_field_name); 7150 ir_build_store_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr, irb->exec->coro_result_field_ptr); 7151 if (irb->codegen->have_err_ret_tracing) { 7152 // initialize the error return trace 7153 Buf *return_addresses_field_name = buf_create_from_str(RETURN_ADDRESSES_FIELD_NAME); 7154 IrInstruction *return_addresses_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, return_addresses_field_name); 7155 7156 Buf *err_ret_trace_field_name = buf_create_from_str(ERR_RET_TRACE_FIELD_NAME); 7157 err_ret_trace_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_field_name); 7158 ir_build_mark_err_ret_trace_ptr(irb, scope, node, err_ret_trace_ptr); 7159 7160 // coordinate with builtin.zig 7161 Buf *index_name = buf_create_from_str("index"); 7162 IrInstruction *index_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, index_name); 7163 ir_build_store_ptr(irb, scope, node, index_ptr, zero); 7164 7165 Buf *instruction_addresses_name = buf_create_from_str("instruction_addresses"); 7166 IrInstruction *addrs_slice_ptr = ir_build_field_ptr(irb, scope, node, err_ret_trace_ptr, instruction_addresses_name); 7167 7168 IrInstruction *slice_value = ir_build_slice(irb, scope, node, return_addresses_ptr, zero, nullptr, false); 7169 ir_build_store_ptr(irb, scope, node, addrs_slice_ptr, slice_value); 7170 } 7171 7172 7173 irb->exec->coro_early_final = ir_create_basic_block(irb, scope, "CoroEarlyFinal"); 7174 irb->exec->coro_normal_final = ir_create_basic_block(irb, scope, "CoroNormalFinal"); 7175 irb->exec->coro_suspend_block = ir_create_basic_block(irb, scope, "Suspend"); 7176 irb->exec->coro_final_cleanup_block = ir_create_basic_block(irb, scope, "FinalCleanup"); 7177 } 7178 7179 IrInstruction *result = ir_gen_node_extra(irb, node, scope, LValNone); 7180 assert(result); 7181 if (irb->exec->invalid) 7182 return false; 7183 7184 if (!instr_is_unreachable(result)) { 7185 // no need for save_err_ret_addr because this cannot return error 7186 ir_gen_async_return(irb, scope, result->source_node, result, true); 7187 } 7188 7189 if (is_async) { 7190 IrBasicBlock *invalid_resume_block = ir_create_basic_block(irb, scope, "InvalidResume"); 7191 IrBasicBlock *check_free_block = ir_create_basic_block(irb, scope, "CheckFree"); 7192 7193 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_early_final); 7194 IrInstruction *const_bool_true = ir_build_const_bool(irb, scope, node, true); 7195 IrInstruction *suspend_code = ir_build_coro_suspend(irb, scope, node, nullptr, const_bool_true); 7196 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(2); 7197 cases[0].value = ir_build_const_u8(irb, scope, node, 0); 7198 cases[0].block = invalid_resume_block; 7199 cases[1].value = ir_build_const_u8(irb, scope, node, 1); 7200 cases[1].block = irb->exec->coro_final_cleanup_block; 7201 ir_build_switch_br(irb, scope, node, suspend_code, irb->exec->coro_suspend_block, 2, cases, const_bool_false, nullptr); 7202 7203 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_suspend_block); 7204 ir_build_coro_end(irb, scope, node); 7205 ir_build_return(irb, scope, node, irb->exec->coro_handle); 7206 7207 ir_set_cursor_at_end_and_append_block(irb, invalid_resume_block); 7208 ir_build_unreachable(irb, scope, node); 7209 7210 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_normal_final); 7211 if (type_has_bits(return_type)) { 7212 IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node, 7213 get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8, 7214 false, false, PtrLenUnknown, 0, 0, 0)); 7215 IrInstruction *result_ptr = ir_build_load_ptr(irb, scope, node, irb->exec->coro_result_ptr_field_ptr); 7216 IrInstruction *result_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len, result_ptr); 7217 IrInstruction *return_value_ptr_as_u8_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len, 7218 irb->exec->coro_result_field_ptr); 7219 IrInstruction *return_type_inst = ir_build_const_type(irb, scope, node, 7220 fn_entry->type_entry->data.fn.fn_type_id.return_type); 7221 IrInstruction *size_of_ret_val = ir_build_size_of(irb, scope, node, return_type_inst); 7222 ir_build_memcpy(irb, scope, node, result_ptr_as_u8_ptr, return_value_ptr_as_u8_ptr, size_of_ret_val); 7223 } 7224 if (irb->codegen->have_err_ret_tracing) { 7225 Buf *err_ret_trace_ptr_field_name = buf_create_from_str(ERR_RET_TRACE_PTR_FIELD_NAME); 7226 IrInstruction *err_ret_trace_ptr_field_ptr = ir_build_field_ptr(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr_field_name); 7227 IrInstruction *dest_err_ret_trace_ptr = ir_build_load_ptr(irb, scope, node, err_ret_trace_ptr_field_ptr); 7228 ir_build_merge_err_ret_traces(irb, scope, node, coro_promise_ptr, err_ret_trace_ptr, dest_err_ret_trace_ptr); 7229 } 7230 // Before we destroy the coroutine frame, we need to load the target promise into 7231 // a register or local variable which does not get spilled into the frame, 7232 // otherwise llvm tries to access memory inside the destroyed frame. 7233 IrInstruction *unwrapped_await_handle_ptr = ir_build_unwrap_maybe(irb, scope, node, 7234 irb->exec->await_handle_var_ptr, false); 7235 IrInstruction *await_handle_in_block = ir_build_load_ptr(irb, scope, node, unwrapped_await_handle_ptr); 7236 ir_build_br(irb, scope, node, check_free_block, const_bool_false); 7237 7238 ir_set_cursor_at_end_and_append_block(irb, irb->exec->coro_final_cleanup_block); 7239 ir_build_br(irb, scope, node, check_free_block, const_bool_false); 7240 7241 ir_set_cursor_at_end_and_append_block(irb, check_free_block); 7242 IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); 7243 IrInstruction **incoming_values = allocate<IrInstruction *>(2); 7244 incoming_blocks[0] = irb->exec->coro_final_cleanup_block; 7245 incoming_values[0] = const_bool_false; 7246 incoming_blocks[1] = irb->exec->coro_normal_final; 7247 incoming_values[1] = const_bool_true; 7248 IrInstruction *resume_awaiter = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); 7249 7250 IrBasicBlock **merge_incoming_blocks = allocate<IrBasicBlock *>(2); 7251 IrInstruction **merge_incoming_values = allocate<IrInstruction *>(2); 7252 merge_incoming_blocks[0] = irb->exec->coro_final_cleanup_block; 7253 merge_incoming_values[0] = ir_build_const_undefined(irb, scope, node); 7254 merge_incoming_blocks[1] = irb->exec->coro_normal_final; 7255 merge_incoming_values[1] = await_handle_in_block; 7256 IrInstruction *awaiter_handle = ir_build_phi(irb, scope, node, 2, merge_incoming_blocks, merge_incoming_values); 7257 7258 Buf *free_field_name = buf_create_from_str(ASYNC_FREE_FIELD_NAME); 7259 IrInstruction *implicit_allocator_ptr = ir_build_get_implicit_allocator(irb, scope, node, 7260 ImplicitAllocatorIdLocalVar); 7261 IrInstruction *free_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, free_field_name); 7262 IrInstruction *free_fn = ir_build_load_ptr(irb, scope, node, free_fn_ptr); 7263 IrInstruction *zero = ir_build_const_usize(irb, scope, node, 0); 7264 IrInstruction *coro_mem_ptr_maybe = ir_build_coro_free(irb, scope, node, coro_id, irb->exec->coro_handle); 7265 IrInstruction *u8_ptr_type_unknown_len = ir_build_const_type(irb, scope, node, 7266 get_pointer_to_type_extra(irb->codegen, irb->codegen->builtin_types.entry_u8, 7267 false, false, PtrLenUnknown, 0, 0, 0)); 7268 IrInstruction *coro_mem_ptr = ir_build_ptr_cast(irb, scope, node, u8_ptr_type_unknown_len, coro_mem_ptr_maybe); 7269 IrInstruction *coro_mem_ptr_ref = ir_build_ref(irb, scope, node, coro_mem_ptr, true, false); 7270 IrInstruction *coro_size_ptr = ir_build_var_ptr(irb, scope, node, coro_size_var); 7271 IrInstruction *coro_size = ir_build_load_ptr(irb, scope, node, coro_size_ptr); 7272 IrInstruction *mem_slice = ir_build_slice(irb, scope, node, coro_mem_ptr_ref, zero, coro_size, false); 7273 size_t arg_count = 2; 7274 IrInstruction **args = allocate<IrInstruction *>(arg_count); 7275 args[0] = implicit_allocator_ptr; // self 7276 args[1] = mem_slice; // old_mem 7277 ir_build_call(irb, scope, node, nullptr, free_fn, arg_count, args, false, FnInlineAuto, false, nullptr, nullptr); 7278 7279 IrBasicBlock *resume_block = ir_create_basic_block(irb, scope, "Resume"); 7280 ir_build_cond_br(irb, scope, node, resume_awaiter, resume_block, irb->exec->coro_suspend_block, const_bool_false); 7281 7282 ir_set_cursor_at_end_and_append_block(irb, resume_block); 7283 ir_gen_resume_target(irb, scope, node, awaiter_handle); 7284 ir_build_br(irb, scope, node, irb->exec->coro_suspend_block, const_bool_false); 7285 } 7286 7287 return true; 7288 } 7289 7290 bool ir_gen_fn(CodeGen *codegen, ZigFn *fn_entry) { 7291 assert(fn_entry); 7292 7293 IrExecutable *ir_executable = &fn_entry->ir_executable; 7294 AstNode *body_node = fn_entry->body_node; 7295 7296 assert(fn_entry->child_scope); 7297 7298 return ir_gen(codegen, body_node, fn_entry->child_scope, ir_executable); 7299 } 7300 7301 static void add_call_stack_errors(CodeGen *codegen, IrExecutable *exec, ErrorMsg *err_msg, int limit) { 7302 if (!exec || !exec->source_node || limit < 0) return; 7303 add_error_note(codegen, err_msg, exec->source_node, buf_sprintf("called from here")); 7304 7305 add_call_stack_errors(codegen, exec->parent_exec, err_msg, limit - 1); 7306 } 7307 7308 static ErrorMsg *exec_add_error_node(CodeGen *codegen, IrExecutable *exec, AstNode *source_node, Buf *msg) { 7309 invalidate_exec(exec); 7310 ErrorMsg *err_msg = add_node_error(codegen, source_node, msg); 7311 if (exec->parent_exec) { 7312 add_call_stack_errors(codegen, exec, err_msg, 10); 7313 } 7314 return err_msg; 7315 } 7316 7317 static ErrorMsg *ir_add_error_node(IrAnalyze *ira, AstNode *source_node, Buf *msg) { 7318 return exec_add_error_node(ira->codegen, ira->new_irb.exec, source_node, msg); 7319 } 7320 7321 static ErrorMsg *ir_add_error(IrAnalyze *ira, IrInstruction *source_instruction, Buf *msg) { 7322 return ir_add_error_node(ira, source_instruction->source_node, msg); 7323 } 7324 7325 static ConstExprValue *ir_const_ptr_pointee(IrAnalyze *ira, ConstExprValue *const_val, AstNode *source_node) { 7326 ConstExprValue *val = const_ptr_pointee_unchecked(ira->codegen, const_val); 7327 assert(val != nullptr); 7328 assert(const_val->type->id == ZigTypeIdPointer); 7329 ZigType *expected_type = const_val->type->data.pointer.child_type; 7330 if (!types_have_same_zig_comptime_repr(val->type, expected_type)) { 7331 ir_add_error_node(ira, source_node, 7332 buf_sprintf("TODO handle comptime reinterpreted pointer. See https://github.com/ziglang/zig/issues/955")); 7333 return nullptr; 7334 } 7335 return val; 7336 } 7337 7338 static IrInstruction *ir_exec_const_result(CodeGen *codegen, IrExecutable *exec) { 7339 IrBasicBlock *bb = exec->basic_block_list.at(0); 7340 for (size_t i = 0; i < bb->instruction_list.length; i += 1) { 7341 IrInstruction *instruction = bb->instruction_list.at(i); 7342 if (instruction->id == IrInstructionIdReturn) { 7343 IrInstructionReturn *ret_inst = (IrInstructionReturn *)instruction; 7344 IrInstruction *value = ret_inst->value; 7345 if (value->value.special == ConstValSpecialRuntime) { 7346 exec_add_error_node(codegen, exec, value->source_node, 7347 buf_sprintf("unable to evaluate constant expression")); 7348 return codegen->invalid_instruction; 7349 } 7350 return value; 7351 } else if (ir_has_side_effects(instruction)) { 7352 exec_add_error_node(codegen, exec, instruction->source_node, 7353 buf_sprintf("unable to evaluate constant expression")); 7354 return codegen->invalid_instruction; 7355 } 7356 } 7357 return codegen->invalid_instruction; 7358 } 7359 7360 static bool ir_emit_global_runtime_side_effect(IrAnalyze *ira, IrInstruction *source_instruction) { 7361 if (ir_should_inline(ira->new_irb.exec, source_instruction->scope)) { 7362 ir_add_error(ira, source_instruction, buf_sprintf("unable to evaluate constant expression")); 7363 return false; 7364 } 7365 return true; 7366 } 7367 7368 static bool const_val_fits_in_num_lit(ConstExprValue *const_val, ZigType *num_lit_type) { 7369 return ((num_lit_type->id == ZigTypeIdComptimeFloat && 7370 (const_val->type->id == ZigTypeIdFloat || const_val->type->id == ZigTypeIdComptimeFloat)) || 7371 (num_lit_type->id == ZigTypeIdComptimeInt && 7372 (const_val->type->id == ZigTypeIdInt || const_val->type->id == ZigTypeIdComptimeInt))); 7373 } 7374 7375 static bool float_has_fraction(ConstExprValue *const_val) { 7376 if (const_val->type->id == ZigTypeIdComptimeFloat) { 7377 return bigfloat_has_fraction(&const_val->data.x_bigfloat); 7378 } else if (const_val->type->id == ZigTypeIdFloat) { 7379 switch (const_val->type->data.floating.bit_count) { 7380 case 16: 7381 { 7382 float16_t floored = f16_roundToInt(const_val->data.x_f16, softfloat_round_minMag, false); 7383 return !f16_eq(floored, const_val->data.x_f16); 7384 } 7385 case 32: 7386 return floorf(const_val->data.x_f32) != const_val->data.x_f32; 7387 case 64: 7388 return floor(const_val->data.x_f64) != const_val->data.x_f64; 7389 case 128: 7390 { 7391 float128_t floored; 7392 f128M_roundToInt(&const_val->data.x_f128, softfloat_round_minMag, false, &floored); 7393 return !f128M_eq(&floored, &const_val->data.x_f128); 7394 } 7395 default: 7396 zig_unreachable(); 7397 } 7398 } else { 7399 zig_unreachable(); 7400 } 7401 } 7402 7403 static void float_append_buf(Buf *buf, ConstExprValue *const_val) { 7404 if (const_val->type->id == ZigTypeIdComptimeFloat) { 7405 bigfloat_append_buf(buf, &const_val->data.x_bigfloat); 7406 } else if (const_val->type->id == ZigTypeIdFloat) { 7407 switch (const_val->type->data.floating.bit_count) { 7408 case 16: 7409 buf_appendf(buf, "%f", zig_f16_to_double(const_val->data.x_f16)); 7410 break; 7411 case 32: 7412 buf_appendf(buf, "%f", const_val->data.x_f32); 7413 break; 7414 case 64: 7415 buf_appendf(buf, "%f", const_val->data.x_f64); 7416 break; 7417 case 128: 7418 { 7419 // TODO actual implementation 7420 const size_t extra_len = 100; 7421 size_t old_len = buf_len(buf); 7422 buf_resize(buf, old_len + extra_len); 7423 7424 float64_t f64_value = f128M_to_f64(&const_val->data.x_f128); 7425 double double_value; 7426 memcpy(&double_value, &f64_value, sizeof(double)); 7427 7428 int len = snprintf(buf_ptr(buf) + old_len, extra_len, "%f", double_value); 7429 assert(len > 0); 7430 buf_resize(buf, old_len + len); 7431 break; 7432 } 7433 default: 7434 zig_unreachable(); 7435 } 7436 } else { 7437 zig_unreachable(); 7438 } 7439 } 7440 7441 static void float_init_bigint(BigInt *bigint, ConstExprValue *const_val) { 7442 if (const_val->type->id == ZigTypeIdComptimeFloat) { 7443 bigint_init_bigfloat(bigint, &const_val->data.x_bigfloat); 7444 } else if (const_val->type->id == ZigTypeIdFloat) { 7445 switch (const_val->type->data.floating.bit_count) { 7446 case 16: 7447 { 7448 double x = zig_f16_to_double(const_val->data.x_f16); 7449 if (x >= 0) { 7450 bigint_init_unsigned(bigint, (uint64_t)x); 7451 } else { 7452 bigint_init_unsigned(bigint, (uint64_t)-x); 7453 bigint->is_negative = true; 7454 } 7455 break; 7456 } 7457 case 32: 7458 if (const_val->data.x_f32 >= 0) { 7459 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f32)); 7460 } else { 7461 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f32)); 7462 bigint->is_negative = true; 7463 } 7464 break; 7465 case 64: 7466 if (const_val->data.x_f64 >= 0) { 7467 bigint_init_unsigned(bigint, (uint64_t)(const_val->data.x_f64)); 7468 } else { 7469 bigint_init_unsigned(bigint, (uint64_t)(-const_val->data.x_f64)); 7470 bigint->is_negative = true; 7471 } 7472 break; 7473 case 128: 7474 { 7475 BigFloat tmp_float; 7476 bigfloat_init_128(&tmp_float, const_val->data.x_f128); 7477 bigint_init_bigfloat(bigint, &tmp_float); 7478 } 7479 break; 7480 default: 7481 zig_unreachable(); 7482 } 7483 } else { 7484 zig_unreachable(); 7485 } 7486 } 7487 7488 static void float_init_bigfloat(ConstExprValue *dest_val, BigFloat *bigfloat) { 7489 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 7490 bigfloat_init_bigfloat(&dest_val->data.x_bigfloat, bigfloat); 7491 } else if (dest_val->type->id == ZigTypeIdFloat) { 7492 switch (dest_val->type->data.floating.bit_count) { 7493 case 16: 7494 dest_val->data.x_f16 = bigfloat_to_f16(bigfloat); 7495 break; 7496 case 32: 7497 dest_val->data.x_f32 = bigfloat_to_f32(bigfloat); 7498 break; 7499 case 64: 7500 dest_val->data.x_f64 = bigfloat_to_f64(bigfloat); 7501 break; 7502 case 128: 7503 dest_val->data.x_f128 = bigfloat_to_f128(bigfloat); 7504 break; 7505 default: 7506 zig_unreachable(); 7507 } 7508 } else { 7509 zig_unreachable(); 7510 } 7511 } 7512 7513 static void float_init_f16(ConstExprValue *dest_val, float16_t x) { 7514 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 7515 bigfloat_init_16(&dest_val->data.x_bigfloat, x); 7516 } else if (dest_val->type->id == ZigTypeIdFloat) { 7517 switch (dest_val->type->data.floating.bit_count) { 7518 case 16: 7519 dest_val->data.x_f16 = x; 7520 break; 7521 case 32: 7522 dest_val->data.x_f32 = zig_f16_to_double(x); 7523 break; 7524 case 64: 7525 dest_val->data.x_f64 = zig_f16_to_double(x); 7526 break; 7527 case 128: 7528 f16_to_f128M(x, &dest_val->data.x_f128); 7529 break; 7530 default: 7531 zig_unreachable(); 7532 } 7533 } else { 7534 zig_unreachable(); 7535 } 7536 } 7537 7538 static void float_init_f32(ConstExprValue *dest_val, float x) { 7539 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 7540 bigfloat_init_32(&dest_val->data.x_bigfloat, x); 7541 } else if (dest_val->type->id == ZigTypeIdFloat) { 7542 switch (dest_val->type->data.floating.bit_count) { 7543 case 16: 7544 dest_val->data.x_f16 = zig_double_to_f16(x); 7545 break; 7546 case 32: 7547 dest_val->data.x_f32 = x; 7548 break; 7549 case 64: 7550 dest_val->data.x_f64 = x; 7551 break; 7552 case 128: 7553 { 7554 float32_t x_f32; 7555 memcpy(&x_f32, &x, sizeof(float)); 7556 f32_to_f128M(x_f32, &dest_val->data.x_f128); 7557 break; 7558 } 7559 default: 7560 zig_unreachable(); 7561 } 7562 } else { 7563 zig_unreachable(); 7564 } 7565 } 7566 7567 static void float_init_f64(ConstExprValue *dest_val, double x) { 7568 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 7569 bigfloat_init_64(&dest_val->data.x_bigfloat, x); 7570 } else if (dest_val->type->id == ZigTypeIdFloat) { 7571 switch (dest_val->type->data.floating.bit_count) { 7572 case 16: 7573 dest_val->data.x_f16 = zig_double_to_f16(x); 7574 break; 7575 case 32: 7576 dest_val->data.x_f32 = x; 7577 break; 7578 case 64: 7579 dest_val->data.x_f64 = x; 7580 break; 7581 case 128: 7582 { 7583 float64_t x_f64; 7584 memcpy(&x_f64, &x, sizeof(double)); 7585 f64_to_f128M(x_f64, &dest_val->data.x_f128); 7586 break; 7587 } 7588 default: 7589 zig_unreachable(); 7590 } 7591 } else { 7592 zig_unreachable(); 7593 } 7594 } 7595 7596 static void float_init_f128(ConstExprValue *dest_val, float128_t x) { 7597 if (dest_val->type->id == ZigTypeIdComptimeFloat) { 7598 bigfloat_init_128(&dest_val->data.x_bigfloat, x); 7599 } else if (dest_val->type->id == ZigTypeIdFloat) { 7600 switch (dest_val->type->data.floating.bit_count) { 7601 case 16: 7602 dest_val->data.x_f16 = f128M_to_f16(&x); 7603 break; 7604 case 32: 7605 { 7606 float32_t f32_val = f128M_to_f32(&x); 7607 memcpy(&dest_val->data.x_f32, &f32_val, sizeof(float)); 7608 break; 7609 } 7610 case 64: 7611 { 7612 float64_t f64_val = f128M_to_f64(&x); 7613 memcpy(&dest_val->data.x_f64, &f64_val, sizeof(double)); 7614 break; 7615 } 7616 case 128: 7617 { 7618 memcpy(&dest_val->data.x_f128, &x, sizeof(float128_t)); 7619 break; 7620 } 7621 default: 7622 zig_unreachable(); 7623 } 7624 } else { 7625 zig_unreachable(); 7626 } 7627 } 7628 7629 static void float_init_float(ConstExprValue *dest_val, ConstExprValue *src_val) { 7630 if (src_val->type->id == ZigTypeIdComptimeFloat) { 7631 float_init_bigfloat(dest_val, &src_val->data.x_bigfloat); 7632 } else if (src_val->type->id == ZigTypeIdFloat) { 7633 switch (src_val->type->data.floating.bit_count) { 7634 case 16: 7635 float_init_f16(dest_val, src_val->data.x_f16); 7636 break; 7637 case 32: 7638 float_init_f32(dest_val, src_val->data.x_f32); 7639 break; 7640 case 64: 7641 float_init_f64(dest_val, src_val->data.x_f64); 7642 break; 7643 case 128: 7644 float_init_f128(dest_val, src_val->data.x_f128); 7645 break; 7646 default: 7647 zig_unreachable(); 7648 } 7649 } else { 7650 zig_unreachable(); 7651 } 7652 } 7653 7654 static Cmp float_cmp(ConstExprValue *op1, ConstExprValue *op2) { 7655 assert(op1->type == op2->type); 7656 if (op1->type->id == ZigTypeIdComptimeFloat) { 7657 return bigfloat_cmp(&op1->data.x_bigfloat, &op2->data.x_bigfloat); 7658 } else if (op1->type->id == ZigTypeIdFloat) { 7659 switch (op1->type->data.floating.bit_count) { 7660 case 16: 7661 if (f16_lt(op1->data.x_f16, op2->data.x_f16)) { 7662 return CmpLT; 7663 } else if (f16_lt(op2->data.x_f16, op1->data.x_f16)) { 7664 return CmpGT; 7665 } else { 7666 return CmpEQ; 7667 } 7668 case 32: 7669 if (op1->data.x_f32 > op2->data.x_f32) { 7670 return CmpGT; 7671 } else if (op1->data.x_f32 < op2->data.x_f32) { 7672 return CmpLT; 7673 } else { 7674 return CmpEQ; 7675 } 7676 case 64: 7677 if (op1->data.x_f64 > op2->data.x_f64) { 7678 return CmpGT; 7679 } else if (op1->data.x_f64 < op2->data.x_f64) { 7680 return CmpLT; 7681 } else { 7682 return CmpEQ; 7683 } 7684 case 128: 7685 if (f128M_lt(&op1->data.x_f128, &op2->data.x_f128)) { 7686 return CmpLT; 7687 } else if (f128M_eq(&op1->data.x_f128, &op2->data.x_f128)) { 7688 return CmpEQ; 7689 } else { 7690 return CmpGT; 7691 } 7692 default: 7693 zig_unreachable(); 7694 } 7695 } else { 7696 zig_unreachable(); 7697 } 7698 } 7699 7700 static Cmp float_cmp_zero(ConstExprValue *op) { 7701 if (op->type->id == ZigTypeIdComptimeFloat) { 7702 return bigfloat_cmp_zero(&op->data.x_bigfloat); 7703 } else if (op->type->id == ZigTypeIdFloat) { 7704 switch (op->type->data.floating.bit_count) { 7705 case 16: 7706 { 7707 const float16_t zero = zig_double_to_f16(0); 7708 if (f16_lt(op->data.x_f16, zero)) { 7709 return CmpLT; 7710 } else if (f16_lt(zero, op->data.x_f16)) { 7711 return CmpGT; 7712 } else { 7713 return CmpEQ; 7714 } 7715 } 7716 case 32: 7717 if (op->data.x_f32 < 0.0) { 7718 return CmpLT; 7719 } else if (op->data.x_f32 > 0.0) { 7720 return CmpGT; 7721 } else { 7722 return CmpEQ; 7723 } 7724 case 64: 7725 if (op->data.x_f64 < 0.0) { 7726 return CmpLT; 7727 } else if (op->data.x_f64 > 0.0) { 7728 return CmpGT; 7729 } else { 7730 return CmpEQ; 7731 } 7732 case 128: 7733 float128_t zero_float; 7734 ui32_to_f128M(0, &zero_float); 7735 if (f128M_lt(&op->data.x_f128, &zero_float)) { 7736 return CmpLT; 7737 } else if (f128M_eq(&op->data.x_f128, &zero_float)) { 7738 return CmpEQ; 7739 } else { 7740 return CmpGT; 7741 } 7742 default: 7743 zig_unreachable(); 7744 } 7745 } else { 7746 zig_unreachable(); 7747 } 7748 } 7749 7750 static void float_add(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 7751 assert(op1->type == op2->type); 7752 out_val->type = op1->type; 7753 if (op1->type->id == ZigTypeIdComptimeFloat) { 7754 bigfloat_add(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 7755 } else if (op1->type->id == ZigTypeIdFloat) { 7756 switch (op1->type->data.floating.bit_count) { 7757 case 16: 7758 out_val->data.x_f16 = f16_add(op1->data.x_f16, op2->data.x_f16); 7759 return; 7760 case 32: 7761 out_val->data.x_f32 = op1->data.x_f32 + op2->data.x_f32; 7762 return; 7763 case 64: 7764 out_val->data.x_f64 = op1->data.x_f64 + op2->data.x_f64; 7765 return; 7766 case 128: 7767 f128M_add(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 7768 return; 7769 default: 7770 zig_unreachable(); 7771 } 7772 } else { 7773 zig_unreachable(); 7774 } 7775 } 7776 7777 static void float_sub(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 7778 assert(op1->type == op2->type); 7779 out_val->type = op1->type; 7780 if (op1->type->id == ZigTypeIdComptimeFloat) { 7781 bigfloat_sub(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 7782 } else if (op1->type->id == ZigTypeIdFloat) { 7783 switch (op1->type->data.floating.bit_count) { 7784 case 16: 7785 out_val->data.x_f16 = f16_sub(op1->data.x_f16, op2->data.x_f16); 7786 return; 7787 case 32: 7788 out_val->data.x_f32 = op1->data.x_f32 - op2->data.x_f32; 7789 return; 7790 case 64: 7791 out_val->data.x_f64 = op1->data.x_f64 - op2->data.x_f64; 7792 return; 7793 case 128: 7794 f128M_sub(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 7795 return; 7796 default: 7797 zig_unreachable(); 7798 } 7799 } else { 7800 zig_unreachable(); 7801 } 7802 } 7803 7804 static void float_mul(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 7805 assert(op1->type == op2->type); 7806 out_val->type = op1->type; 7807 if (op1->type->id == ZigTypeIdComptimeFloat) { 7808 bigfloat_mul(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 7809 } else if (op1->type->id == ZigTypeIdFloat) { 7810 switch (op1->type->data.floating.bit_count) { 7811 case 16: 7812 out_val->data.x_f16 = f16_mul(op1->data.x_f16, op2->data.x_f16); 7813 return; 7814 case 32: 7815 out_val->data.x_f32 = op1->data.x_f32 * op2->data.x_f32; 7816 return; 7817 case 64: 7818 out_val->data.x_f64 = op1->data.x_f64 * op2->data.x_f64; 7819 return; 7820 case 128: 7821 f128M_mul(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 7822 return; 7823 default: 7824 zig_unreachable(); 7825 } 7826 } else { 7827 zig_unreachable(); 7828 } 7829 } 7830 7831 static void float_div(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 7832 assert(op1->type == op2->type); 7833 out_val->type = op1->type; 7834 if (op1->type->id == ZigTypeIdComptimeFloat) { 7835 bigfloat_div(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 7836 } else if (op1->type->id == ZigTypeIdFloat) { 7837 switch (op1->type->data.floating.bit_count) { 7838 case 16: 7839 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 7840 return; 7841 case 32: 7842 out_val->data.x_f32 = op1->data.x_f32 / op2->data.x_f32; 7843 return; 7844 case 64: 7845 out_val->data.x_f64 = op1->data.x_f64 / op2->data.x_f64; 7846 return; 7847 case 128: 7848 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 7849 return; 7850 default: 7851 zig_unreachable(); 7852 } 7853 } else { 7854 zig_unreachable(); 7855 } 7856 } 7857 7858 static void float_div_trunc(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 7859 assert(op1->type == op2->type); 7860 out_val->type = op1->type; 7861 if (op1->type->id == ZigTypeIdComptimeFloat) { 7862 bigfloat_div_trunc(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 7863 } else if (op1->type->id == ZigTypeIdFloat) { 7864 switch (op1->type->data.floating.bit_count) { 7865 case 16: 7866 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 7867 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_minMag, false); 7868 return; 7869 case 32: 7870 out_val->data.x_f32 = truncf(op1->data.x_f32 / op2->data.x_f32); 7871 return; 7872 case 64: 7873 out_val->data.x_f64 = trunc(op1->data.x_f64 / op2->data.x_f64); 7874 return; 7875 case 128: 7876 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 7877 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_minMag, false, &out_val->data.x_f128); 7878 return; 7879 default: 7880 zig_unreachable(); 7881 } 7882 } else { 7883 zig_unreachable(); 7884 } 7885 } 7886 7887 static void float_div_floor(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 7888 assert(op1->type == op2->type); 7889 out_val->type = op1->type; 7890 if (op1->type->id == ZigTypeIdComptimeFloat) { 7891 bigfloat_div_floor(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 7892 } else if (op1->type->id == ZigTypeIdFloat) { 7893 switch (op1->type->data.floating.bit_count) { 7894 case 16: 7895 out_val->data.x_f16 = f16_div(op1->data.x_f16, op2->data.x_f16); 7896 out_val->data.x_f16 = f16_roundToInt(out_val->data.x_f16, softfloat_round_min, false); 7897 return; 7898 case 32: 7899 out_val->data.x_f32 = floorf(op1->data.x_f32 / op2->data.x_f32); 7900 return; 7901 case 64: 7902 out_val->data.x_f64 = floor(op1->data.x_f64 / op2->data.x_f64); 7903 return; 7904 case 128: 7905 f128M_div(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 7906 f128M_roundToInt(&out_val->data.x_f128, softfloat_round_min, false, &out_val->data.x_f128); 7907 return; 7908 default: 7909 zig_unreachable(); 7910 } 7911 } else { 7912 zig_unreachable(); 7913 } 7914 } 7915 7916 static void float_rem(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 7917 assert(op1->type == op2->type); 7918 out_val->type = op1->type; 7919 if (op1->type->id == ZigTypeIdComptimeFloat) { 7920 bigfloat_rem(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 7921 } else if (op1->type->id == ZigTypeIdFloat) { 7922 switch (op1->type->data.floating.bit_count) { 7923 case 16: 7924 out_val->data.x_f16 = f16_rem(op1->data.x_f16, op2->data.x_f16); 7925 return; 7926 case 32: 7927 out_val->data.x_f32 = fmodf(op1->data.x_f32, op2->data.x_f32); 7928 return; 7929 case 64: 7930 out_val->data.x_f64 = fmod(op1->data.x_f64, op2->data.x_f64); 7931 return; 7932 case 128: 7933 f128M_rem(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 7934 return; 7935 default: 7936 zig_unreachable(); 7937 } 7938 } else { 7939 zig_unreachable(); 7940 } 7941 } 7942 7943 // c = a - b * trunc(a / b) 7944 static float16_t zig_f16_mod(float16_t a, float16_t b) { 7945 float16_t c; 7946 c = f16_div(a, b); 7947 c = f16_roundToInt(c, softfloat_round_min, true); 7948 c = f16_mul(b, c); 7949 c = f16_sub(a, c); 7950 return c; 7951 } 7952 7953 // c = a - b * trunc(a / b) 7954 static void zig_f128M_mod(const float128_t* a, const float128_t* b, float128_t* c) { 7955 f128M_div(a, b, c); 7956 f128M_roundToInt(c, softfloat_round_min, true, c); 7957 f128M_mul(b, c, c); 7958 f128M_sub(a, c, c); 7959 } 7960 7961 static void float_mod(ConstExprValue *out_val, ConstExprValue *op1, ConstExprValue *op2) { 7962 assert(op1->type == op2->type); 7963 out_val->type = op1->type; 7964 if (op1->type->id == ZigTypeIdComptimeFloat) { 7965 bigfloat_mod(&out_val->data.x_bigfloat, &op1->data.x_bigfloat, &op2->data.x_bigfloat); 7966 } else if (op1->type->id == ZigTypeIdFloat) { 7967 switch (op1->type->data.floating.bit_count) { 7968 case 16: 7969 out_val->data.x_f16 = zig_f16_mod(op1->data.x_f16, op2->data.x_f16); 7970 return; 7971 case 32: 7972 out_val->data.x_f32 = fmodf(fmodf(op1->data.x_f32, op2->data.x_f32) + op2->data.x_f32, op2->data.x_f32); 7973 return; 7974 case 64: 7975 out_val->data.x_f64 = fmod(fmod(op1->data.x_f64, op2->data.x_f64) + op2->data.x_f64, op2->data.x_f64); 7976 return; 7977 case 128: 7978 zig_f128M_mod(&op1->data.x_f128, &op2->data.x_f128, &out_val->data.x_f128); 7979 return; 7980 default: 7981 zig_unreachable(); 7982 } 7983 } else { 7984 zig_unreachable(); 7985 } 7986 } 7987 7988 static void float_negate(ConstExprValue *out_val, ConstExprValue *op) { 7989 out_val->type = op->type; 7990 if (op->type->id == ZigTypeIdComptimeFloat) { 7991 bigfloat_negate(&out_val->data.x_bigfloat, &op->data.x_bigfloat); 7992 } else if (op->type->id == ZigTypeIdFloat) { 7993 switch (op->type->data.floating.bit_count) { 7994 case 16: 7995 { 7996 const float16_t zero = zig_double_to_f16(0); 7997 out_val->data.x_f16 = f16_sub(zero, op->data.x_f16); 7998 return; 7999 } 8000 case 32: 8001 out_val->data.x_f32 = -op->data.x_f32; 8002 return; 8003 case 64: 8004 out_val->data.x_f64 = -op->data.x_f64; 8005 return; 8006 case 128: 8007 float128_t zero_f128; 8008 ui32_to_f128M(0, &zero_f128); 8009 f128M_sub(&zero_f128, &op->data.x_f128, &out_val->data.x_f128); 8010 return; 8011 default: 8012 zig_unreachable(); 8013 } 8014 } else { 8015 zig_unreachable(); 8016 } 8017 } 8018 8019 void float_write_ieee597(ConstExprValue *op, uint8_t *buf, bool is_big_endian) { 8020 if (op->type->id == ZigTypeIdFloat) { 8021 switch (op->type->data.floating.bit_count) { 8022 case 16: 8023 memcpy(buf, &op->data.x_f16, 2); // TODO wrong when compiler is big endian 8024 return; 8025 case 32: 8026 memcpy(buf, &op->data.x_f32, 4); // TODO wrong when compiler is big endian 8027 return; 8028 case 64: 8029 memcpy(buf, &op->data.x_f64, 8); // TODO wrong when compiler is big endian 8030 return; 8031 case 128: 8032 memcpy(buf, &op->data.x_f128, 16); // TODO wrong when compiler is big endian 8033 return; 8034 default: 8035 zig_unreachable(); 8036 } 8037 } else { 8038 zig_unreachable(); 8039 } 8040 } 8041 8042 void float_read_ieee597(ConstExprValue *val, uint8_t *buf, bool is_big_endian) { 8043 if (val->type->id == ZigTypeIdFloat) { 8044 switch (val->type->data.floating.bit_count) { 8045 case 16: 8046 memcpy(&val->data.x_f16, buf, 2); // TODO wrong when compiler is big endian 8047 return; 8048 case 32: 8049 memcpy(&val->data.x_f32, buf, 4); // TODO wrong when compiler is big endian 8050 return; 8051 case 64: 8052 memcpy(&val->data.x_f64, buf, 8); // TODO wrong when compiler is big endian 8053 return; 8054 case 128: 8055 memcpy(&val->data.x_f128, buf, 16); // TODO wrong when compiler is big endian 8056 return; 8057 default: 8058 zig_unreachable(); 8059 } 8060 } else { 8061 zig_unreachable(); 8062 } 8063 } 8064 8065 static bool ir_num_lit_fits_in_other_type(IrAnalyze *ira, IrInstruction *instruction, ZigType *other_type, 8066 bool explicit_cast) 8067 { 8068 if (type_is_invalid(other_type)) { 8069 return false; 8070 } 8071 8072 ConstExprValue *const_val = &instruction->value; 8073 assert(const_val->special != ConstValSpecialRuntime); 8074 8075 bool const_val_is_int = (const_val->type->id == ZigTypeIdInt || 8076 const_val->type->id == ZigTypeIdComptimeInt); 8077 bool const_val_is_float = (const_val->type->id == ZigTypeIdFloat || 8078 const_val->type->id == ZigTypeIdComptimeFloat); 8079 if (other_type->id == ZigTypeIdFloat) { 8080 return true; 8081 } else if (other_type->id == ZigTypeIdInt && const_val_is_int) { 8082 if (!other_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 8083 Buf *val_buf = buf_alloc(); 8084 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 8085 ir_add_error(ira, instruction, 8086 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 8087 buf_ptr(val_buf), 8088 buf_ptr(&other_type->name))); 8089 return false; 8090 } 8091 if (bigint_fits_in_bits(&const_val->data.x_bigint, other_type->data.integral.bit_count, 8092 other_type->data.integral.is_signed)) 8093 { 8094 return true; 8095 } 8096 } else if (const_val_fits_in_num_lit(const_val, other_type)) { 8097 return true; 8098 } else if (other_type->id == ZigTypeIdOptional) { 8099 ZigType *child_type = other_type->data.maybe.child_type; 8100 if (const_val_fits_in_num_lit(const_val, child_type)) { 8101 return true; 8102 } else if (child_type->id == ZigTypeIdInt && const_val_is_int) { 8103 if (!child_type->data.integral.is_signed && const_val->data.x_bigint.is_negative) { 8104 Buf *val_buf = buf_alloc(); 8105 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 8106 ir_add_error(ira, instruction, 8107 buf_sprintf("cannot cast negative value %s to unsigned integer type '%s'", 8108 buf_ptr(val_buf), 8109 buf_ptr(&child_type->name))); 8110 return false; 8111 } 8112 if (bigint_fits_in_bits(&const_val->data.x_bigint, 8113 child_type->data.integral.bit_count, 8114 child_type->data.integral.is_signed)) 8115 { 8116 return true; 8117 } 8118 } else if (child_type->id == ZigTypeIdFloat && const_val_is_float) { 8119 return true; 8120 } 8121 } 8122 if (explicit_cast && (other_type->id == ZigTypeIdInt || other_type->id == ZigTypeIdComptimeInt) && 8123 const_val_is_float) 8124 { 8125 if (float_has_fraction(const_val)) { 8126 Buf *val_buf = buf_alloc(); 8127 float_append_buf(val_buf, const_val); 8128 8129 ir_add_error(ira, instruction, 8130 buf_sprintf("fractional component prevents float value %s from being casted to type '%s'", 8131 buf_ptr(val_buf), 8132 buf_ptr(&other_type->name))); 8133 return false; 8134 } else { 8135 if (other_type->id == ZigTypeIdComptimeInt) { 8136 return true; 8137 } else { 8138 BigInt bigint; 8139 float_init_bigint(&bigint, const_val); 8140 if (bigint_fits_in_bits(&bigint, other_type->data.integral.bit_count, 8141 other_type->data.integral.is_signed)) 8142 { 8143 return true; 8144 } 8145 } 8146 } 8147 } 8148 8149 const char *num_lit_str; 8150 Buf *val_buf = buf_alloc(); 8151 if (const_val_is_float) { 8152 num_lit_str = "float"; 8153 float_append_buf(val_buf, const_val); 8154 } else { 8155 num_lit_str = "integer"; 8156 bigint_append_buf(val_buf, &const_val->data.x_bigint, 10); 8157 } 8158 8159 ir_add_error(ira, instruction, 8160 buf_sprintf("%s value %s cannot be implicitly casted to type '%s'", 8161 num_lit_str, 8162 buf_ptr(val_buf), 8163 buf_ptr(&other_type->name))); 8164 return false; 8165 } 8166 8167 static bool is_slice(ZigType *type) { 8168 return type->id == ZigTypeIdStruct && type->data.structure.is_slice; 8169 } 8170 8171 static bool slice_is_const(ZigType *type) { 8172 assert(is_slice(type)); 8173 return type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; 8174 } 8175 8176 static ZigType *get_error_set_intersection(IrAnalyze *ira, ZigType *set1, ZigType *set2, 8177 AstNode *source_node) 8178 { 8179 assert(set1->id == ZigTypeIdErrorSet); 8180 assert(set2->id == ZigTypeIdErrorSet); 8181 8182 if (!resolve_inferred_error_set(ira->codegen, set1, source_node)) { 8183 return ira->codegen->builtin_types.entry_invalid; 8184 } 8185 if (!resolve_inferred_error_set(ira->codegen, set2, source_node)) { 8186 return ira->codegen->builtin_types.entry_invalid; 8187 } 8188 if (type_is_global_error_set(set1)) { 8189 return set2; 8190 } 8191 if (type_is_global_error_set(set2)) { 8192 return set1; 8193 } 8194 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 8195 for (uint32_t i = 0; i < set1->data.error_set.err_count; i += 1) { 8196 ErrorTableEntry *error_entry = set1->data.error_set.errors[i]; 8197 assert(errors[error_entry->value] == nullptr); 8198 errors[error_entry->value] = error_entry; 8199 } 8200 ZigList<ErrorTableEntry *> intersection_list = {}; 8201 8202 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); 8203 buf_resize(&err_set_type->name, 0); 8204 buf_appendf(&err_set_type->name, "error.{"); 8205 8206 for (uint32_t i = 0; i < set2->data.error_set.err_count; i += 1) { 8207 ErrorTableEntry *error_entry = set2->data.error_set.errors[i]; 8208 ErrorTableEntry *existing_entry = errors[error_entry->value]; 8209 if (existing_entry != nullptr) { 8210 intersection_list.append(existing_entry); 8211 buf_appendf(&err_set_type->name, "%s,", buf_ptr(&existing_entry->name)); 8212 } 8213 } 8214 free(errors); 8215 8216 err_set_type->type_ref = ira->codegen->builtin_types.entry_global_error_set->type_ref; 8217 err_set_type->di_type = ira->codegen->builtin_types.entry_global_error_set->di_type; 8218 err_set_type->data.error_set.err_count = intersection_list.length; 8219 err_set_type->data.error_set.errors = intersection_list.items; 8220 err_set_type->zero_bits = intersection_list.length == 0; 8221 8222 buf_appendf(&err_set_type->name, "}"); 8223 8224 ira->codegen->error_di_types.append(&err_set_type->di_type); 8225 8226 return err_set_type; 8227 } 8228 8229 8230 static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted_type, 8231 ZigType *actual_type, AstNode *source_node, bool wanted_is_mutable) 8232 { 8233 CodeGen *g = ira->codegen; 8234 ConstCastOnly result = {}; 8235 result.id = ConstCastResultIdOk; 8236 8237 Error err; 8238 8239 if (wanted_type == actual_type) 8240 return result; 8241 8242 // *T and [*]T may const-cast-only to ?*U and ?[*]U, respectively 8243 // but not if we want a mutable pointer 8244 // and not if the actual pointer has zero bits 8245 if (!wanted_is_mutable && wanted_type->id == ZigTypeIdOptional && 8246 wanted_type->data.maybe.child_type->id == ZigTypeIdPointer && 8247 actual_type->id == ZigTypeIdPointer && type_has_bits(actual_type)) 8248 { 8249 ConstCastOnly child = types_match_const_cast_only(ira, 8250 wanted_type->data.maybe.child_type, actual_type, source_node, wanted_is_mutable); 8251 if (child.id == ConstCastResultIdInvalid) 8252 return child; 8253 if (child.id != ConstCastResultIdOk) { 8254 result.id = ConstCastResultIdNullWrapPtr; 8255 result.data.null_wrap_ptr_child = allocate_nonzero<ConstCastOnly>(1); 8256 *result.data.null_wrap_ptr_child = child; 8257 } 8258 return result; 8259 } 8260 8261 // pointer const 8262 if (wanted_type->id == ZigTypeIdPointer && actual_type->id == ZigTypeIdPointer) { 8263 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 8264 actual_type->data.pointer.child_type, source_node, !wanted_type->data.pointer.is_const); 8265 if (child.id == ConstCastResultIdInvalid) 8266 return child; 8267 if (child.id != ConstCastResultIdOk) { 8268 result.id = ConstCastResultIdPointerChild; 8269 result.data.pointer_mismatch = allocate_nonzero<ConstCastPointerMismatch>(1); 8270 result.data.pointer_mismatch->child = child; 8271 result.data.pointer_mismatch->wanted_child = wanted_type->data.pointer.child_type; 8272 result.data.pointer_mismatch->actual_child = actual_type->data.pointer.child_type; 8273 return result; 8274 } 8275 if ((err = type_resolve(g, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 8276 result.id = ConstCastResultIdInvalid; 8277 return result; 8278 } 8279 if ((err = type_resolve(g, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 8280 result.id = ConstCastResultIdInvalid; 8281 return result; 8282 } 8283 if ((actual_type->data.pointer.ptr_len == wanted_type->data.pointer.ptr_len) && 8284 (!actual_type->data.pointer.is_const || wanted_type->data.pointer.is_const) && 8285 (!actual_type->data.pointer.is_volatile || wanted_type->data.pointer.is_volatile) && 8286 actual_type->data.pointer.bit_offset_in_host == wanted_type->data.pointer.bit_offset_in_host && 8287 actual_type->data.pointer.host_int_bytes == wanted_type->data.pointer.host_int_bytes && 8288 get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type)) 8289 { 8290 return result; 8291 } 8292 } 8293 8294 // slice const 8295 if (is_slice(wanted_type) && is_slice(actual_type)) { 8296 ZigType *actual_ptr_type = actual_type->data.structure.fields[slice_ptr_index].type_entry; 8297 ZigType *wanted_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 8298 if ((err = type_resolve(g, actual_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 8299 result.id = ConstCastResultIdInvalid; 8300 return result; 8301 } 8302 if ((err = type_resolve(g, wanted_ptr_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) { 8303 result.id = ConstCastResultIdInvalid; 8304 return result; 8305 } 8306 if ((!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) && 8307 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) && 8308 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host && 8309 actual_ptr_type->data.pointer.host_int_bytes == wanted_ptr_type->data.pointer.host_int_bytes && 8310 get_ptr_align(g, actual_ptr_type) >= get_ptr_align(g, wanted_ptr_type)) 8311 { 8312 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type, 8313 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const); 8314 if (child.id == ConstCastResultIdInvalid) 8315 return child; 8316 if (child.id != ConstCastResultIdOk) { 8317 result.id = ConstCastResultIdSliceChild; 8318 result.data.slice_mismatch = allocate_nonzero<ConstCastSliceMismatch>(1); 8319 result.data.slice_mismatch->child = child; 8320 result.data.slice_mismatch->actual_child = actual_ptr_type->data.pointer.child_type; 8321 result.data.slice_mismatch->wanted_child = wanted_ptr_type->data.pointer.child_type; 8322 } 8323 return result; 8324 } 8325 } 8326 8327 // maybe 8328 if (wanted_type->id == ZigTypeIdOptional && actual_type->id == ZigTypeIdOptional) { 8329 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.maybe.child_type, 8330 actual_type->data.maybe.child_type, source_node, wanted_is_mutable); 8331 if (child.id == ConstCastResultIdInvalid) 8332 return child; 8333 if (child.id != ConstCastResultIdOk) { 8334 result.id = ConstCastResultIdOptionalChild; 8335 result.data.optional = allocate_nonzero<ConstCastOptionalMismatch>(1); 8336 result.data.optional->child = child; 8337 result.data.optional->wanted_child = wanted_type->data.maybe.child_type; 8338 result.data.optional->actual_child = actual_type->data.maybe.child_type; 8339 } 8340 return result; 8341 } 8342 8343 // error union 8344 if (wanted_type->id == ZigTypeIdErrorUnion && actual_type->id == ZigTypeIdErrorUnion) { 8345 ConstCastOnly payload_child = types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, 8346 actual_type->data.error_union.payload_type, source_node, wanted_is_mutable); 8347 if (payload_child.id == ConstCastResultIdInvalid) 8348 return payload_child; 8349 if (payload_child.id != ConstCastResultIdOk) { 8350 result.id = ConstCastResultIdErrorUnionPayload; 8351 result.data.error_union_payload = allocate_nonzero<ConstCastErrUnionPayloadMismatch>(1); 8352 result.data.error_union_payload->child = payload_child; 8353 result.data.error_union_payload->wanted_payload = wanted_type->data.error_union.payload_type; 8354 result.data.error_union_payload->actual_payload = actual_type->data.error_union.payload_type; 8355 return result; 8356 } 8357 ConstCastOnly error_set_child = types_match_const_cast_only(ira, wanted_type->data.error_union.err_set_type, 8358 actual_type->data.error_union.err_set_type, source_node, wanted_is_mutable); 8359 if (error_set_child.id == ConstCastResultIdInvalid) 8360 return error_set_child; 8361 if (error_set_child.id != ConstCastResultIdOk) { 8362 result.id = ConstCastResultIdErrorUnionErrorSet; 8363 result.data.error_union_error_set = allocate_nonzero<ConstCastErrUnionErrSetMismatch>(1); 8364 result.data.error_union_error_set->child = error_set_child; 8365 result.data.error_union_error_set->wanted_err_set = wanted_type->data.error_union.err_set_type; 8366 result.data.error_union_error_set->actual_err_set = actual_type->data.error_union.err_set_type; 8367 return result; 8368 } 8369 return result; 8370 } 8371 8372 // error set 8373 if (wanted_type->id == ZigTypeIdErrorSet && actual_type->id == ZigTypeIdErrorSet) { 8374 ZigType *contained_set = actual_type; 8375 ZigType *container_set = wanted_type; 8376 8377 // if the container set is inferred, then this will always work. 8378 if (container_set->data.error_set.infer_fn != nullptr) { 8379 return result; 8380 } 8381 // if the container set is the global one, it will always work. 8382 if (type_is_global_error_set(container_set)) { 8383 return result; 8384 } 8385 8386 if (!resolve_inferred_error_set(ira->codegen, contained_set, source_node)) { 8387 result.id = ConstCastResultIdUnresolvedInferredErrSet; 8388 return result; 8389 } 8390 8391 if (type_is_global_error_set(contained_set)) { 8392 result.id = ConstCastResultIdErrSetGlobal; 8393 return result; 8394 } 8395 8396 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(g->errors_by_index.length); 8397 for (uint32_t i = 0; i < container_set->data.error_set.err_count; i += 1) { 8398 ErrorTableEntry *error_entry = container_set->data.error_set.errors[i]; 8399 assert(errors[error_entry->value] == nullptr); 8400 errors[error_entry->value] = error_entry; 8401 } 8402 for (uint32_t i = 0; i < contained_set->data.error_set.err_count; i += 1) { 8403 ErrorTableEntry *contained_error_entry = contained_set->data.error_set.errors[i]; 8404 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 8405 if (error_entry == nullptr) { 8406 if (result.id == ConstCastResultIdOk) { 8407 result.id = ConstCastResultIdErrSet; 8408 result.data.error_set_mismatch = allocate<ConstCastErrSetMismatch>(1); 8409 } 8410 result.data.error_set_mismatch->missing_errors.append(contained_error_entry); 8411 } 8412 } 8413 free(errors); 8414 return result; 8415 } 8416 8417 if (wanted_type == ira->codegen->builtin_types.entry_promise && 8418 actual_type->id == ZigTypeIdPromise) 8419 { 8420 return result; 8421 } 8422 8423 // fn 8424 if (wanted_type->id == ZigTypeIdFn && 8425 actual_type->id == ZigTypeIdFn) 8426 { 8427 if (wanted_type->data.fn.fn_type_id.alignment > actual_type->data.fn.fn_type_id.alignment) { 8428 result.id = ConstCastResultIdFnAlign; 8429 return result; 8430 } 8431 if (wanted_type->data.fn.fn_type_id.cc != actual_type->data.fn.fn_type_id.cc) { 8432 result.id = ConstCastResultIdFnCC; 8433 return result; 8434 } 8435 if (wanted_type->data.fn.fn_type_id.is_var_args != actual_type->data.fn.fn_type_id.is_var_args) { 8436 result.id = ConstCastResultIdFnVarArgs; 8437 return result; 8438 } 8439 if (wanted_type->data.fn.is_generic != actual_type->data.fn.is_generic) { 8440 result.id = ConstCastResultIdFnIsGeneric; 8441 return result; 8442 } 8443 if (!wanted_type->data.fn.is_generic && 8444 actual_type->data.fn.fn_type_id.return_type->id != ZigTypeIdUnreachable) 8445 { 8446 ConstCastOnly child = types_match_const_cast_only(ira, wanted_type->data.fn.fn_type_id.return_type, 8447 actual_type->data.fn.fn_type_id.return_type, source_node, false); 8448 if (child.id == ConstCastResultIdInvalid) 8449 return child; 8450 if (child.id != ConstCastResultIdOk) { 8451 result.id = ConstCastResultIdFnReturnType; 8452 result.data.return_type = allocate_nonzero<ConstCastOnly>(1); 8453 *result.data.return_type = child; 8454 return result; 8455 } 8456 } 8457 if (!wanted_type->data.fn.is_generic && wanted_type->data.fn.fn_type_id.cc == CallingConventionAsync) { 8458 ConstCastOnly child = types_match_const_cast_only(ira, 8459 actual_type->data.fn.fn_type_id.async_allocator_type, 8460 wanted_type->data.fn.fn_type_id.async_allocator_type, 8461 source_node, false); 8462 if (child.id == ConstCastResultIdInvalid) 8463 return child; 8464 if (child.id != ConstCastResultIdOk) { 8465 result.id = ConstCastResultIdAsyncAllocatorType; 8466 result.data.async_allocator_type = allocate_nonzero<ConstCastOnly>(1); 8467 *result.data.async_allocator_type = child; 8468 return result; 8469 } 8470 } 8471 if (wanted_type->data.fn.fn_type_id.param_count != actual_type->data.fn.fn_type_id.param_count) { 8472 result.id = ConstCastResultIdFnArgCount; 8473 return result; 8474 } 8475 if (wanted_type->data.fn.fn_type_id.next_param_index != actual_type->data.fn.fn_type_id.next_param_index) { 8476 result.id = ConstCastResultIdFnGenericArgCount; 8477 return result; 8478 } 8479 assert(wanted_type->data.fn.is_generic || 8480 wanted_type->data.fn.fn_type_id.next_param_index == wanted_type->data.fn.fn_type_id.param_count); 8481 for (size_t i = 0; i < wanted_type->data.fn.fn_type_id.next_param_index; i += 1) { 8482 // note it's reversed for parameters 8483 FnTypeParamInfo *actual_param_info = &actual_type->data.fn.fn_type_id.param_info[i]; 8484 FnTypeParamInfo *expected_param_info = &wanted_type->data.fn.fn_type_id.param_info[i]; 8485 8486 ConstCastOnly arg_child = types_match_const_cast_only(ira, actual_param_info->type, 8487 expected_param_info->type, source_node, false); 8488 if (arg_child.id == ConstCastResultIdInvalid) 8489 return arg_child; 8490 if (arg_child.id != ConstCastResultIdOk) { 8491 result.id = ConstCastResultIdFnArg; 8492 result.data.fn_arg.arg_index = i; 8493 result.data.fn_arg.child = allocate_nonzero<ConstCastOnly>(1); 8494 *result.data.fn_arg.child = arg_child; 8495 return result; 8496 } 8497 8498 if (expected_param_info->is_noalias != actual_param_info->is_noalias) { 8499 result.id = ConstCastResultIdFnArgNoAlias; 8500 result.data.arg_no_alias.arg_index = i; 8501 return result; 8502 } 8503 } 8504 return result; 8505 } 8506 8507 result.id = ConstCastResultIdType; 8508 result.data.type_mismatch = allocate_nonzero<ConstCastTypeMismatch>(1); 8509 result.data.type_mismatch->wanted_type = wanted_type; 8510 result.data.type_mismatch->actual_type = actual_type; 8511 return result; 8512 } 8513 8514 static void update_errors_helper(CodeGen *g, ErrorTableEntry ***errors, size_t *errors_count) { 8515 size_t old_errors_count = *errors_count; 8516 *errors_count = g->errors_by_index.length; 8517 *errors = reallocate(*errors, old_errors_count, *errors_count); 8518 } 8519 8520 static ZigType *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_node, ZigType *expected_type, IrInstruction **instructions, size_t instruction_count) { 8521 Error err; 8522 assert(instruction_count >= 1); 8523 IrInstruction *prev_inst = instructions[0]; 8524 if (type_is_invalid(prev_inst->value.type)) { 8525 return ira->codegen->builtin_types.entry_invalid; 8526 } 8527 ErrorTableEntry **errors = nullptr; 8528 size_t errors_count = 0; 8529 ZigType *err_set_type = nullptr; 8530 if (prev_inst->value.type->id == ZigTypeIdErrorSet) { 8531 if (type_is_global_error_set(prev_inst->value.type)) { 8532 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 8533 } else { 8534 err_set_type = prev_inst->value.type; 8535 if (!resolve_inferred_error_set(ira->codegen, err_set_type, prev_inst->source_node)) { 8536 return ira->codegen->builtin_types.entry_invalid; 8537 } 8538 update_errors_helper(ira->codegen, &errors, &errors_count); 8539 8540 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8541 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 8542 assert(errors[error_entry->value] == nullptr); 8543 errors[error_entry->value] = error_entry; 8544 } 8545 } 8546 } 8547 8548 bool any_are_null = (prev_inst->value.type->id == ZigTypeIdNull); 8549 bool convert_to_const_slice = false; 8550 for (size_t i = 1; i < instruction_count; i += 1) { 8551 IrInstruction *cur_inst = instructions[i]; 8552 ZigType *cur_type = cur_inst->value.type; 8553 ZigType *prev_type = prev_inst->value.type; 8554 8555 if (type_is_invalid(cur_type)) { 8556 return cur_type; 8557 } 8558 8559 if (prev_type->id == ZigTypeIdUnreachable) { 8560 prev_inst = cur_inst; 8561 continue; 8562 } 8563 8564 if (cur_type->id == ZigTypeIdUnreachable) { 8565 continue; 8566 } 8567 8568 if (prev_type->id == ZigTypeIdErrorSet) { 8569 assert(err_set_type != nullptr); 8570 if (cur_type->id == ZigTypeIdErrorSet) { 8571 if (type_is_global_error_set(err_set_type)) { 8572 continue; 8573 } 8574 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { 8575 return ira->codegen->builtin_types.entry_invalid; 8576 } 8577 if (type_is_global_error_set(cur_type)) { 8578 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 8579 prev_inst = cur_inst; 8580 continue; 8581 } 8582 8583 // number of declared errors might have increased now 8584 update_errors_helper(ira->codegen, &errors, &errors_count); 8585 8586 // if err_set_type is a superset of cur_type, keep err_set_type. 8587 // if cur_type is a superset of err_set_type, switch err_set_type to cur_type 8588 bool prev_is_superset = true; 8589 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 8590 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 8591 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 8592 if (error_entry == nullptr) { 8593 prev_is_superset = false; 8594 break; 8595 } 8596 } 8597 if (prev_is_superset) { 8598 continue; 8599 } 8600 8601 // unset everything in errors 8602 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8603 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 8604 errors[error_entry->value] = nullptr; 8605 } 8606 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 8607 assert(errors[i] == nullptr); 8608 } 8609 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 8610 ErrorTableEntry *error_entry = cur_type->data.error_set.errors[i]; 8611 assert(errors[error_entry->value] == nullptr); 8612 errors[error_entry->value] = error_entry; 8613 } 8614 bool cur_is_superset = true; 8615 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8616 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 8617 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 8618 if (error_entry == nullptr) { 8619 cur_is_superset = false; 8620 break; 8621 } 8622 } 8623 if (cur_is_superset) { 8624 err_set_type = cur_type; 8625 prev_inst = cur_inst; 8626 assert(errors != nullptr); 8627 continue; 8628 } 8629 8630 // neither of them are supersets. so we invent a new error set type that is a union of both of them 8631 err_set_type = get_error_set_union(ira->codegen, errors, cur_type, err_set_type); 8632 assert(errors != nullptr); 8633 continue; 8634 } else if (cur_type->id == ZigTypeIdErrorUnion) { 8635 if (type_is_global_error_set(err_set_type)) { 8636 prev_inst = cur_inst; 8637 continue; 8638 } 8639 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 8640 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 8641 return ira->codegen->builtin_types.entry_invalid; 8642 } 8643 if (type_is_global_error_set(cur_err_set_type)) { 8644 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 8645 prev_inst = cur_inst; 8646 continue; 8647 } 8648 8649 update_errors_helper(ira->codegen, &errors, &errors_count); 8650 8651 // test if err_set_type is a subset of cur_type's error set 8652 // unset everything in errors 8653 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8654 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 8655 errors[error_entry->value] = nullptr; 8656 } 8657 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 8658 assert(errors[i] == nullptr); 8659 } 8660 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 8661 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 8662 assert(errors[error_entry->value] == nullptr); 8663 errors[error_entry->value] = error_entry; 8664 } 8665 bool cur_is_superset = true; 8666 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8667 ErrorTableEntry *contained_error_entry = err_set_type->data.error_set.errors[i]; 8668 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 8669 if (error_entry == nullptr) { 8670 cur_is_superset = false; 8671 break; 8672 } 8673 } 8674 if (cur_is_superset) { 8675 err_set_type = cur_err_set_type; 8676 prev_inst = cur_inst; 8677 assert(errors != nullptr); 8678 continue; 8679 } 8680 8681 // not a subset. invent new error set type, union of both of them 8682 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, err_set_type); 8683 prev_inst = cur_inst; 8684 assert(errors != nullptr); 8685 continue; 8686 } else { 8687 prev_inst = cur_inst; 8688 continue; 8689 } 8690 } 8691 8692 if (cur_type->id == ZigTypeIdErrorSet) { 8693 if (prev_type->id == ZigTypeIdArray) { 8694 convert_to_const_slice = true; 8695 } 8696 if (type_is_global_error_set(cur_type)) { 8697 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 8698 continue; 8699 } 8700 if (err_set_type != nullptr && type_is_global_error_set(err_set_type)) { 8701 continue; 8702 } 8703 if (!resolve_inferred_error_set(ira->codegen, cur_type, cur_inst->source_node)) { 8704 return ira->codegen->builtin_types.entry_invalid; 8705 } 8706 8707 update_errors_helper(ira->codegen, &errors, &errors_count); 8708 8709 if (err_set_type == nullptr) { 8710 if (prev_type->id == ZigTypeIdErrorUnion) { 8711 err_set_type = prev_type->data.error_union.err_set_type; 8712 } else { 8713 err_set_type = cur_type; 8714 } 8715 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8716 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 8717 assert(errors[error_entry->value] == nullptr); 8718 errors[error_entry->value] = error_entry; 8719 } 8720 if (err_set_type == cur_type) { 8721 continue; 8722 } 8723 } 8724 // check if the cur type error set is a subset 8725 bool prev_is_superset = true; 8726 for (uint32_t i = 0; i < cur_type->data.error_set.err_count; i += 1) { 8727 ErrorTableEntry *contained_error_entry = cur_type->data.error_set.errors[i]; 8728 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 8729 if (error_entry == nullptr) { 8730 prev_is_superset = false; 8731 break; 8732 } 8733 } 8734 if (prev_is_superset) { 8735 continue; 8736 } 8737 // not a subset. invent new error set type, union of both of them 8738 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_type); 8739 assert(errors != nullptr); 8740 continue; 8741 } 8742 8743 if (prev_type->id == ZigTypeIdErrorUnion && cur_type->id == ZigTypeIdErrorUnion) { 8744 ZigType *prev_payload_type = prev_type->data.error_union.payload_type; 8745 ZigType *cur_payload_type = cur_type->data.error_union.payload_type; 8746 8747 bool const_cast_prev = types_match_const_cast_only(ira, prev_payload_type, cur_payload_type, 8748 source_node, false).id == ConstCastResultIdOk; 8749 bool const_cast_cur = types_match_const_cast_only(ira, cur_payload_type, prev_payload_type, 8750 source_node, false).id == ConstCastResultIdOk; 8751 8752 if (const_cast_prev || const_cast_cur) { 8753 if (const_cast_cur) { 8754 prev_inst = cur_inst; 8755 } 8756 8757 ZigType *prev_err_set_type = (err_set_type == nullptr) ? prev_type->data.error_union.err_set_type : err_set_type; 8758 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 8759 8760 if (!resolve_inferred_error_set(ira->codegen, prev_err_set_type, cur_inst->source_node)) { 8761 return ira->codegen->builtin_types.entry_invalid; 8762 } 8763 8764 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 8765 return ira->codegen->builtin_types.entry_invalid; 8766 } 8767 8768 if (type_is_global_error_set(prev_err_set_type) || type_is_global_error_set(cur_err_set_type)) { 8769 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 8770 continue; 8771 } 8772 8773 update_errors_helper(ira->codegen, &errors, &errors_count); 8774 8775 if (err_set_type == nullptr) { 8776 err_set_type = prev_err_set_type; 8777 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 8778 ErrorTableEntry *error_entry = prev_err_set_type->data.error_set.errors[i]; 8779 assert(errors[error_entry->value] == nullptr); 8780 errors[error_entry->value] = error_entry; 8781 } 8782 } 8783 bool prev_is_superset = true; 8784 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 8785 ErrorTableEntry *contained_error_entry = cur_err_set_type->data.error_set.errors[i]; 8786 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 8787 if (error_entry == nullptr) { 8788 prev_is_superset = false; 8789 break; 8790 } 8791 } 8792 if (prev_is_superset) { 8793 continue; 8794 } 8795 // unset all the errors 8796 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 8797 ErrorTableEntry *error_entry = err_set_type->data.error_set.errors[i]; 8798 errors[error_entry->value] = nullptr; 8799 } 8800 for (uint32_t i = 0, count = ira->codegen->errors_by_index.length; i < count; i += 1) { 8801 assert(errors[i] == nullptr); 8802 } 8803 for (uint32_t i = 0; i < cur_err_set_type->data.error_set.err_count; i += 1) { 8804 ErrorTableEntry *error_entry = cur_err_set_type->data.error_set.errors[i]; 8805 assert(errors[error_entry->value] == nullptr); 8806 errors[error_entry->value] = error_entry; 8807 } 8808 bool cur_is_superset = true; 8809 for (uint32_t i = 0; i < prev_err_set_type->data.error_set.err_count; i += 1) { 8810 ErrorTableEntry *contained_error_entry = prev_err_set_type->data.error_set.errors[i]; 8811 ErrorTableEntry *error_entry = errors[contained_error_entry->value]; 8812 if (error_entry == nullptr) { 8813 cur_is_superset = false; 8814 break; 8815 } 8816 } 8817 if (cur_is_superset) { 8818 err_set_type = cur_err_set_type; 8819 continue; 8820 } 8821 8822 err_set_type = get_error_set_union(ira->codegen, errors, cur_err_set_type, prev_err_set_type); 8823 continue; 8824 } 8825 } 8826 8827 if (prev_type->id == ZigTypeIdNull) { 8828 prev_inst = cur_inst; 8829 continue; 8830 } 8831 8832 if (cur_type->id == ZigTypeIdNull) { 8833 any_are_null = true; 8834 continue; 8835 } 8836 8837 if (types_match_const_cast_only(ira, prev_type, cur_type, source_node, false).id == ConstCastResultIdOk) { 8838 continue; 8839 } 8840 8841 if (types_match_const_cast_only(ira, cur_type, prev_type, source_node, false).id == ConstCastResultIdOk) { 8842 prev_inst = cur_inst; 8843 continue; 8844 } 8845 8846 if (prev_type->id == ZigTypeIdInt && 8847 cur_type->id == ZigTypeIdInt && 8848 prev_type->data.integral.is_signed == cur_type->data.integral.is_signed) 8849 { 8850 if (cur_type->data.integral.bit_count > prev_type->data.integral.bit_count) { 8851 prev_inst = cur_inst; 8852 } 8853 continue; 8854 } 8855 8856 if (prev_type->id == ZigTypeIdFloat && cur_type->id == ZigTypeIdFloat) { 8857 if (cur_type->data.floating.bit_count > prev_type->data.floating.bit_count) { 8858 prev_inst = cur_inst; 8859 } 8860 continue; 8861 } 8862 8863 if (prev_type->id == ZigTypeIdErrorUnion && 8864 types_match_const_cast_only(ira, prev_type->data.error_union.payload_type, cur_type, 8865 source_node, false).id == ConstCastResultIdOk) 8866 { 8867 continue; 8868 } 8869 8870 if (cur_type->id == ZigTypeIdErrorUnion && 8871 types_match_const_cast_only(ira, cur_type->data.error_union.payload_type, prev_type, 8872 source_node, false).id == ConstCastResultIdOk) 8873 { 8874 if (err_set_type != nullptr) { 8875 ZigType *cur_err_set_type = cur_type->data.error_union.err_set_type; 8876 if (!resolve_inferred_error_set(ira->codegen, cur_err_set_type, cur_inst->source_node)) { 8877 return ira->codegen->builtin_types.entry_invalid; 8878 } 8879 if (type_is_global_error_set(cur_err_set_type) || type_is_global_error_set(err_set_type)) { 8880 err_set_type = ira->codegen->builtin_types.entry_global_error_set; 8881 prev_inst = cur_inst; 8882 continue; 8883 } 8884 8885 update_errors_helper(ira->codegen, &errors, &errors_count); 8886 8887 err_set_type = get_error_set_union(ira->codegen, errors, err_set_type, cur_err_set_type); 8888 } 8889 prev_inst = cur_inst; 8890 continue; 8891 } 8892 8893 if (prev_type->id == ZigTypeIdOptional && 8894 types_match_const_cast_only(ira, prev_type->data.maybe.child_type, cur_type, 8895 source_node, false).id == ConstCastResultIdOk) 8896 { 8897 continue; 8898 } 8899 8900 if (cur_type->id == ZigTypeIdOptional && 8901 types_match_const_cast_only(ira, cur_type->data.maybe.child_type, prev_type, 8902 source_node, false).id == ConstCastResultIdOk) 8903 { 8904 prev_inst = cur_inst; 8905 continue; 8906 } 8907 8908 if (cur_type->id == ZigTypeIdUndefined) { 8909 continue; 8910 } 8911 8912 if (prev_type->id == ZigTypeIdUndefined) { 8913 prev_inst = cur_inst; 8914 continue; 8915 } 8916 8917 if (prev_type->id == ZigTypeIdComptimeInt || 8918 prev_type->id == ZigTypeIdComptimeFloat) 8919 { 8920 if (ir_num_lit_fits_in_other_type(ira, prev_inst, cur_type, false)) { 8921 prev_inst = cur_inst; 8922 continue; 8923 } else { 8924 return ira->codegen->builtin_types.entry_invalid; 8925 } 8926 } 8927 8928 if (cur_type->id == ZigTypeIdComptimeInt || 8929 cur_type->id == ZigTypeIdComptimeFloat) 8930 { 8931 if (ir_num_lit_fits_in_other_type(ira, cur_inst, prev_type, false)) { 8932 continue; 8933 } else { 8934 return ira->codegen->builtin_types.entry_invalid; 8935 } 8936 } 8937 8938 if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && 8939 cur_type->data.array.len != prev_type->data.array.len && 8940 types_match_const_cast_only(ira, cur_type->data.array.child_type, prev_type->data.array.child_type, 8941 source_node, false).id == ConstCastResultIdOk) 8942 { 8943 convert_to_const_slice = true; 8944 prev_inst = cur_inst; 8945 continue; 8946 } 8947 8948 if (cur_type->id == ZigTypeIdArray && prev_type->id == ZigTypeIdArray && 8949 cur_type->data.array.len != prev_type->data.array.len && 8950 types_match_const_cast_only(ira, prev_type->data.array.child_type, cur_type->data.array.child_type, 8951 source_node, false).id == ConstCastResultIdOk) 8952 { 8953 convert_to_const_slice = true; 8954 continue; 8955 } 8956 8957 if (cur_type->id == ZigTypeIdArray && is_slice(prev_type) && 8958 (prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || 8959 cur_type->data.array.len == 0) && 8960 types_match_const_cast_only(ira, 8961 prev_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, 8962 cur_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 8963 { 8964 convert_to_const_slice = false; 8965 continue; 8966 } 8967 8968 if (prev_type->id == ZigTypeIdArray && is_slice(cur_type) && 8969 (cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const || 8970 prev_type->data.array.len == 0) && 8971 types_match_const_cast_only(ira, 8972 cur_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.child_type, 8973 prev_type->data.array.child_type, source_node, false).id == ConstCastResultIdOk) 8974 { 8975 prev_inst = cur_inst; 8976 convert_to_const_slice = false; 8977 continue; 8978 } 8979 8980 if (prev_type->id == ZigTypeIdEnum && cur_type->id == ZigTypeIdUnion && 8981 (cur_type->data.unionation.decl_node->data.container_decl.auto_enum || cur_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 8982 { 8983 if ((err = type_resolve(ira->codegen, cur_type, ResolveStatusZeroBitsKnown))) 8984 return ira->codegen->builtin_types.entry_invalid; 8985 if (cur_type->data.unionation.tag_type == prev_type) { 8986 continue; 8987 } 8988 } 8989 8990 if (cur_type->id == ZigTypeIdEnum && prev_type->id == ZigTypeIdUnion && 8991 (prev_type->data.unionation.decl_node->data.container_decl.auto_enum || prev_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 8992 { 8993 if ((err = type_resolve(ira->codegen, prev_type, ResolveStatusZeroBitsKnown))) 8994 return ira->codegen->builtin_types.entry_invalid; 8995 if (prev_type->data.unionation.tag_type == cur_type) { 8996 prev_inst = cur_inst; 8997 continue; 8998 } 8999 } 9000 9001 ErrorMsg *msg = ir_add_error_node(ira, source_node, 9002 buf_sprintf("incompatible types: '%s' and '%s'", 9003 buf_ptr(&prev_type->name), buf_ptr(&cur_type->name))); 9004 add_error_note(ira->codegen, msg, prev_inst->source_node, 9005 buf_sprintf("type '%s' here", buf_ptr(&prev_type->name))); 9006 add_error_note(ira->codegen, msg, cur_inst->source_node, 9007 buf_sprintf("type '%s' here", buf_ptr(&cur_type->name))); 9008 9009 return ira->codegen->builtin_types.entry_invalid; 9010 } 9011 9012 free(errors); 9013 9014 if (convert_to_const_slice) { 9015 assert(prev_inst->value.type->id == ZigTypeIdArray); 9016 ZigType *ptr_type = get_pointer_to_type_extra( 9017 ira->codegen, prev_inst->value.type->data.array.child_type, 9018 true, false, PtrLenUnknown, 9019 0, 0, 0); 9020 ZigType *slice_type = get_slice_type(ira->codegen, ptr_type); 9021 if (err_set_type != nullptr) { 9022 return get_error_union_type(ira->codegen, err_set_type, slice_type); 9023 } else { 9024 return slice_type; 9025 } 9026 } else if (err_set_type != nullptr) { 9027 if (prev_inst->value.type->id == ZigTypeIdErrorSet) { 9028 return err_set_type; 9029 } else if (prev_inst->value.type->id == ZigTypeIdErrorUnion) { 9030 ZigType *payload_type = prev_inst->value.type->data.error_union.payload_type; 9031 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 9032 return ira->codegen->builtin_types.entry_invalid; 9033 return get_error_union_type(ira->codegen, err_set_type, payload_type); 9034 } else if (expected_type != nullptr && expected_type->id == ZigTypeIdErrorUnion) { 9035 ZigType *payload_type = expected_type->data.error_union.payload_type; 9036 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 9037 return ira->codegen->builtin_types.entry_invalid; 9038 return get_error_union_type(ira->codegen, err_set_type, payload_type); 9039 } else { 9040 if (prev_inst->value.type->id == ZigTypeIdComptimeInt || 9041 prev_inst->value.type->id == ZigTypeIdComptimeFloat) 9042 { 9043 ir_add_error_node(ira, source_node, 9044 buf_sprintf("unable to make error union out of number literal")); 9045 return ira->codegen->builtin_types.entry_invalid; 9046 } else if (prev_inst->value.type->id == ZigTypeIdNull) { 9047 ir_add_error_node(ira, source_node, 9048 buf_sprintf("unable to make error union out of null literal")); 9049 return ira->codegen->builtin_types.entry_invalid; 9050 } else { 9051 if ((err = type_resolve(ira->codegen, prev_inst->value.type, ResolveStatusSizeKnown))) 9052 return ira->codegen->builtin_types.entry_invalid; 9053 return get_error_union_type(ira->codegen, err_set_type, prev_inst->value.type); 9054 } 9055 } 9056 } else if (any_are_null && prev_inst->value.type->id != ZigTypeIdNull) { 9057 if (prev_inst->value.type->id == ZigTypeIdComptimeInt || 9058 prev_inst->value.type->id == ZigTypeIdComptimeFloat) 9059 { 9060 ir_add_error_node(ira, source_node, 9061 buf_sprintf("unable to make maybe out of number literal")); 9062 return ira->codegen->builtin_types.entry_invalid; 9063 } else if (prev_inst->value.type->id == ZigTypeIdOptional) { 9064 return prev_inst->value.type; 9065 } else { 9066 return get_optional_type(ira->codegen, prev_inst->value.type); 9067 } 9068 } else { 9069 return prev_inst->value.type; 9070 } 9071 } 9072 9073 static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, ZigType *type_entry) { 9074 if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) { 9075 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 9076 if (fn_entry != nullptr) { 9077 fn_entry->alloca_list.append(instruction); 9078 } 9079 } 9080 } 9081 9082 static void copy_const_val(ConstExprValue *dest, ConstExprValue *src, bool same_global_refs) { 9083 ConstGlobalRefs *global_refs = dest->global_refs; 9084 *dest = *src; 9085 if (!same_global_refs) { 9086 dest->global_refs = global_refs; 9087 if (dest->type->id == ZigTypeIdStruct) { 9088 dest->data.x_struct.fields = allocate_nonzero<ConstExprValue>(dest->type->data.structure.src_field_count); 9089 memcpy(dest->data.x_struct.fields, src->data.x_struct.fields, sizeof(ConstExprValue) * dest->type->data.structure.src_field_count); 9090 } 9091 } 9092 } 9093 9094 static bool eval_const_expr_implicit_cast(IrAnalyze *ira, IrInstruction *source_instr, 9095 CastOp cast_op, 9096 ConstExprValue *other_val, ZigType *other_type, 9097 ConstExprValue *const_val, ZigType *new_type) 9098 { 9099 const_val->special = other_val->special; 9100 9101 assert(other_val != const_val); 9102 switch (cast_op) { 9103 case CastOpNoCast: 9104 zig_unreachable(); 9105 case CastOpErrSet: 9106 case CastOpBitCast: 9107 case CastOpPtrOfArrayToSlice: 9108 zig_panic("TODO"); 9109 case CastOpNoop: 9110 { 9111 bool same_global_refs = other_val->special == ConstValSpecialStatic; 9112 copy_const_val(const_val, other_val, same_global_refs); 9113 const_val->type = new_type; 9114 break; 9115 } 9116 case CastOpNumLitToConcrete: 9117 if (other_val->type->id == ZigTypeIdComptimeFloat) { 9118 assert(new_type->id == ZigTypeIdFloat); 9119 switch (new_type->data.floating.bit_count) { 9120 case 16: 9121 const_val->data.x_f16 = bigfloat_to_f16(&other_val->data.x_bigfloat); 9122 break; 9123 case 32: 9124 const_val->data.x_f32 = bigfloat_to_f32(&other_val->data.x_bigfloat); 9125 break; 9126 case 64: 9127 const_val->data.x_f64 = bigfloat_to_f64(&other_val->data.x_bigfloat); 9128 break; 9129 case 128: 9130 const_val->data.x_f128 = bigfloat_to_f128(&other_val->data.x_bigfloat); 9131 break; 9132 default: 9133 zig_unreachable(); 9134 } 9135 } else if (other_val->type->id == ZigTypeIdComptimeInt) { 9136 bigint_init_bigint(&const_val->data.x_bigint, &other_val->data.x_bigint); 9137 } else { 9138 zig_unreachable(); 9139 } 9140 const_val->type = new_type; 9141 break; 9142 case CastOpResizeSlice: 9143 case CastOpBytesToSlice: 9144 // can't do it 9145 zig_unreachable(); 9146 case CastOpIntToFloat: 9147 { 9148 assert(new_type->id == ZigTypeIdFloat); 9149 9150 BigFloat bigfloat; 9151 bigfloat_init_bigint(&bigfloat, &other_val->data.x_bigint); 9152 switch (new_type->data.floating.bit_count) { 9153 case 16: 9154 const_val->data.x_f16 = bigfloat_to_f16(&bigfloat); 9155 break; 9156 case 32: 9157 const_val->data.x_f32 = bigfloat_to_f32(&bigfloat); 9158 break; 9159 case 64: 9160 const_val->data.x_f64 = bigfloat_to_f64(&bigfloat); 9161 break; 9162 case 128: 9163 const_val->data.x_f128 = bigfloat_to_f128(&bigfloat); 9164 break; 9165 default: 9166 zig_unreachable(); 9167 } 9168 const_val->special = ConstValSpecialStatic; 9169 break; 9170 } 9171 case CastOpFloatToInt: 9172 float_init_bigint(&const_val->data.x_bigint, other_val); 9173 if (new_type->id == ZigTypeIdInt) { 9174 if (!bigint_fits_in_bits(&const_val->data.x_bigint, new_type->data.integral.bit_count, 9175 new_type->data.integral.is_signed)) 9176 { 9177 Buf *int_buf = buf_alloc(); 9178 bigint_append_buf(int_buf, &const_val->data.x_bigint, 10); 9179 9180 ir_add_error(ira, source_instr, 9181 buf_sprintf("integer value '%s' cannot be stored in type '%s'", 9182 buf_ptr(int_buf), buf_ptr(&new_type->name))); 9183 return false; 9184 } 9185 } 9186 9187 const_val->special = ConstValSpecialStatic; 9188 break; 9189 case CastOpBoolToInt: 9190 bigint_init_unsigned(&const_val->data.x_bigint, other_val->data.x_bool ? 1 : 0); 9191 const_val->special = ConstValSpecialStatic; 9192 break; 9193 } 9194 return true; 9195 } 9196 static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 9197 ZigType *wanted_type, CastOp cast_op, bool need_alloca) 9198 { 9199 if ((instr_is_comptime(value) || !type_has_bits(wanted_type)) && 9200 cast_op != CastOpResizeSlice && cast_op != CastOpBytesToSlice) 9201 { 9202 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9203 source_instr->source_node, wanted_type); 9204 if (!eval_const_expr_implicit_cast(ira, source_instr, cast_op, &value->value, value->value.type, 9205 &result->value, wanted_type)) 9206 { 9207 return ira->codegen->invalid_instruction; 9208 } 9209 return result; 9210 } else { 9211 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op); 9212 result->value.type = wanted_type; 9213 if (need_alloca) { 9214 ir_add_alloca(ira, result, wanted_type); 9215 } 9216 return result; 9217 } 9218 } 9219 9220 static IrInstruction *ir_resolve_ptr_of_array_to_unknown_len_ptr(IrAnalyze *ira, IrInstruction *source_instr, 9221 IrInstruction *value, ZigType *wanted_type) 9222 { 9223 assert(value->value.type->id == ZigTypeIdPointer); 9224 9225 Error err; 9226 9227 if ((err = type_resolve(ira->codegen, value->value.type->data.pointer.child_type, 9228 ResolveStatusAlignmentKnown))) 9229 { 9230 return ira->codegen->invalid_instruction; 9231 } 9232 9233 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value.type)); 9234 9235 if (instr_is_comptime(value)) { 9236 ConstExprValue *pointee = ir_const_ptr_pointee(ira, &value->value, source_instr->source_node); 9237 if (pointee == nullptr) 9238 return ira->codegen->invalid_instruction; 9239 if (pointee->special != ConstValSpecialRuntime) { 9240 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9241 source_instr->source_node, wanted_type); 9242 result->value.type = wanted_type; 9243 result->value.data.x_ptr.special = ConstPtrSpecialBaseArray; 9244 result->value.data.x_ptr.mut = value->value.data.x_ptr.mut; 9245 result->value.data.x_ptr.data.base_array.array_val = pointee; 9246 result->value.data.x_ptr.data.base_array.elem_index = 0; 9247 result->value.data.x_ptr.data.base_array.is_cstr = false; 9248 return result; 9249 } 9250 } 9251 9252 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 9253 wanted_type, value, CastOpBitCast); 9254 result->value.type = wanted_type; 9255 return result; 9256 } 9257 9258 static IrInstruction *ir_resolve_ptr_of_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, 9259 IrInstruction *value, ZigType *wanted_type) 9260 { 9261 Error err; 9262 9263 if ((err = type_resolve(ira->codegen, value->value.type->data.pointer.child_type, 9264 ResolveStatusAlignmentKnown))) 9265 { 9266 return ira->codegen->invalid_instruction; 9267 } 9268 9269 wanted_type = adjust_slice_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, value->value.type)); 9270 9271 if (instr_is_comptime(value)) { 9272 ConstExprValue *pointee = ir_const_ptr_pointee(ira, &value->value, source_instr->source_node); 9273 if (pointee == nullptr) 9274 return ira->codegen->invalid_instruction; 9275 if (pointee->special != ConstValSpecialRuntime) { 9276 assert(value->value.type->id == ZigTypeIdPointer); 9277 ZigType *array_type = value->value.type->data.pointer.child_type; 9278 assert(is_slice(wanted_type)); 9279 bool is_const = wanted_type->data.structure.fields[slice_ptr_index].type_entry->data.pointer.is_const; 9280 9281 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9282 source_instr->source_node, wanted_type); 9283 init_const_slice(ira->codegen, &result->value, pointee, 0, array_type->data.array.len, is_const); 9284 result->value.data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = 9285 value->value.data.x_ptr.mut; 9286 result->value.type = wanted_type; 9287 return result; 9288 } 9289 } 9290 9291 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, 9292 wanted_type, value, CastOpPtrOfArrayToSlice); 9293 result->value.type = wanted_type; 9294 ir_add_alloca(ira, result, wanted_type); 9295 return result; 9296 } 9297 9298 static bool is_container(ZigType *type) { 9299 return type->id == ZigTypeIdStruct || 9300 type->id == ZigTypeIdEnum || 9301 type->id == ZigTypeIdUnion; 9302 } 9303 9304 static IrBasicBlock *ir_get_new_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { 9305 assert(old_bb); 9306 9307 if (old_bb->other) { 9308 if (ref_old_instruction == nullptr || old_bb->other->ref_instruction != ref_old_instruction) { 9309 return old_bb->other; 9310 } 9311 } 9312 9313 IrBasicBlock *new_bb = ir_build_bb_from(&ira->new_irb, old_bb); 9314 new_bb->ref_instruction = ref_old_instruction; 9315 9316 return new_bb; 9317 } 9318 9319 static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, IrInstruction *ref_old_instruction) { 9320 assert(ref_old_instruction != nullptr); 9321 IrBasicBlock *new_bb = ir_get_new_bb(ira, old_bb, ref_old_instruction); 9322 if (new_bb->must_be_comptime_source_instr) { 9323 ErrorMsg *msg = ir_add_error(ira, ref_old_instruction, 9324 buf_sprintf("control flow attempts to use compile-time variable at runtime")); 9325 add_error_note(ira->codegen, msg, new_bb->must_be_comptime_source_instr->source_node, 9326 buf_sprintf("compile-time variable assigned here")); 9327 return nullptr; 9328 } 9329 return new_bb; 9330 } 9331 9332 static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { 9333 ira->instruction_index = 0; 9334 ira->old_irb.current_basic_block = old_bb; 9335 ira->const_predecessor_bb = const_predecessor_bb; 9336 } 9337 9338 static void ir_finish_bb(IrAnalyze *ira) { 9339 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block); 9340 ira->instruction_index += 1; 9341 while (ira->instruction_index < ira->old_irb.current_basic_block->instruction_list.length) { 9342 IrInstruction *next_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 9343 if (!next_instruction->is_gen) { 9344 ir_add_error(ira, next_instruction, buf_sprintf("unreachable code")); 9345 break; 9346 } 9347 ira->instruction_index += 1; 9348 } 9349 9350 ira->old_bb_index += 1; 9351 9352 bool need_repeat = true; 9353 for (;;) { 9354 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 9355 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index); 9356 if (old_bb->other == nullptr) { 9357 ira->old_bb_index += 1; 9358 continue; 9359 } 9360 if (old_bb->other->instruction_list.length != 0) { 9361 ira->old_bb_index += 1; 9362 continue; 9363 } 9364 ira->new_irb.current_basic_block = old_bb->other; 9365 9366 ir_start_bb(ira, old_bb, nullptr); 9367 return; 9368 } 9369 if (!need_repeat) 9370 return; 9371 need_repeat = false; 9372 ira->old_bb_index = 0; 9373 continue; 9374 } 9375 } 9376 9377 static IrInstruction *ir_unreach_error(IrAnalyze *ira) { 9378 ira->old_bb_index = SIZE_MAX; 9379 ira->new_irb.exec->invalid = true; 9380 return ira->codegen->unreach_instruction; 9381 } 9382 9383 static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instruction) { 9384 size_t *bbc = ira->new_irb.exec->backward_branch_count; 9385 size_t quota = ira->new_irb.exec->backward_branch_quota; 9386 9387 // If we're already over quota, we've already given an error message for this. 9388 if (*bbc > quota) { 9389 return false; 9390 } 9391 9392 *bbc += 1; 9393 if (*bbc > quota) { 9394 ir_add_error(ira, source_instruction, buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", quota)); 9395 return false; 9396 } 9397 return true; 9398 } 9399 9400 static IrInstruction *ir_inline_bb(IrAnalyze *ira, IrInstruction *source_instruction, IrBasicBlock *old_bb) { 9401 if (old_bb->debug_id <= ira->old_irb.current_basic_block->debug_id) { 9402 if (!ir_emit_backward_branch(ira, source_instruction)) 9403 return ir_unreach_error(ira); 9404 } 9405 9406 old_bb->other = ira->old_irb.current_basic_block->other; 9407 ir_start_bb(ira, old_bb, ira->old_irb.current_basic_block); 9408 return ira->codegen->unreach_instruction; 9409 } 9410 9411 static IrInstruction *ir_finish_anal(IrAnalyze *ira, IrInstruction *instruction) { 9412 if (instruction->value.type->id == ZigTypeIdUnreachable) 9413 ir_finish_bb(ira); 9414 return instruction; 9415 } 9416 9417 static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, ZigType *ty) { 9418 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 9419 old_instruction->scope, old_instruction->source_node); 9420 IrInstruction *new_instruction = &const_instruction->base; 9421 new_instruction->value.type = ty; 9422 new_instruction->value.special = ConstValSpecialStatic; 9423 return new_instruction; 9424 } 9425 9426 static IrInstruction *ir_const_type(IrAnalyze *ira, IrInstruction *source_instruction, ZigType *ty) { 9427 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_type); 9428 result->value.data.x_type = ty; 9429 return result; 9430 } 9431 9432 static IrInstruction *ir_const_bool(IrAnalyze *ira, IrInstruction *source_instruction, bool value) { 9433 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_bool); 9434 result->value.data.x_bool = value; 9435 return result; 9436 } 9437 9438 static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { 9439 return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void); 9440 } 9441 9442 static IrInstruction *ir_const_unsigned(IrAnalyze *ira, IrInstruction *source_instruction, uint64_t value) { 9443 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_num_lit_int); 9444 bigint_init_unsigned(&result->value.data.x_bigint, value); 9445 return result; 9446 } 9447 9448 static IrInstruction *ir_const_usize(IrAnalyze *ira, IrInstruction *source_instruction, uint64_t value) { 9449 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_usize); 9450 bigint_init_unsigned(&result->value.data.x_bigint, value); 9451 return result; 9452 } 9453 9454 static IrInstruction *ir_get_const_ptr(IrAnalyze *ira, IrInstruction *instruction, 9455 ConstExprValue *pointee, ZigType *pointee_type, 9456 ConstPtrMut ptr_mut, bool ptr_is_const, bool ptr_is_volatile, uint32_t ptr_align) 9457 { 9458 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, pointee_type, 9459 ptr_is_const, ptr_is_volatile, PtrLenSingle, ptr_align, 0, 0); 9460 IrInstruction *const_instr = ir_const(ira, instruction, ptr_type); 9461 ConstExprValue *const_val = &const_instr->value; 9462 const_val->data.x_ptr.special = ConstPtrSpecialRef; 9463 const_val->data.x_ptr.mut = ptr_mut; 9464 const_val->data.x_ptr.data.ref.pointee = pointee; 9465 return const_instr; 9466 } 9467 9468 enum UndefAllowed { 9469 UndefOk, 9470 UndefBad, 9471 }; 9472 9473 static ConstExprValue *ir_resolve_const(IrAnalyze *ira, IrInstruction *value, UndefAllowed undef_allowed) { 9474 switch (value->value.special) { 9475 case ConstValSpecialStatic: 9476 return &value->value; 9477 case ConstValSpecialRuntime: 9478 if (!type_has_bits(value->value.type)) { 9479 return &value->value; 9480 } 9481 ir_add_error(ira, value, buf_sprintf("unable to evaluate constant expression")); 9482 return nullptr; 9483 case ConstValSpecialUndef: 9484 if (undef_allowed == UndefOk) { 9485 return &value->value; 9486 } else { 9487 ir_add_error(ira, value, buf_sprintf("use of undefined value")); 9488 return nullptr; 9489 } 9490 } 9491 zig_unreachable(); 9492 } 9493 9494 IrInstruction *ir_eval_const_value(CodeGen *codegen, Scope *scope, AstNode *node, 9495 ZigType *expected_type, size_t *backward_branch_count, size_t backward_branch_quota, 9496 ZigFn *fn_entry, Buf *c_import_buf, AstNode *source_node, Buf *exec_name, 9497 IrExecutable *parent_exec) 9498 { 9499 if (expected_type != nullptr && type_is_invalid(expected_type)) 9500 return codegen->invalid_instruction; 9501 9502 IrExecutable *ir_executable = allocate<IrExecutable>(1); 9503 ir_executable->source_node = source_node; 9504 ir_executable->parent_exec = parent_exec; 9505 ir_executable->name = exec_name; 9506 ir_executable->is_inline = true; 9507 ir_executable->fn_entry = fn_entry; 9508 ir_executable->c_import_buf = c_import_buf; 9509 ir_executable->begin_scope = scope; 9510 ir_gen(codegen, node, scope, ir_executable); 9511 9512 if (ir_executable->invalid) 9513 return codegen->invalid_instruction; 9514 9515 if (codegen->verbose_ir) { 9516 fprintf(stderr, "\nSource: "); 9517 ast_render(codegen, stderr, node, 4); 9518 fprintf(stderr, "\n{ // (IR)\n"); 9519 ir_print(codegen, stderr, ir_executable, 4); 9520 fprintf(stderr, "}\n"); 9521 } 9522 IrExecutable *analyzed_executable = allocate<IrExecutable>(1); 9523 analyzed_executable->source_node = source_node; 9524 analyzed_executable->parent_exec = parent_exec; 9525 analyzed_executable->source_exec = ir_executable; 9526 analyzed_executable->name = exec_name; 9527 analyzed_executable->is_inline = true; 9528 analyzed_executable->fn_entry = fn_entry; 9529 analyzed_executable->c_import_buf = c_import_buf; 9530 analyzed_executable->backward_branch_count = backward_branch_count; 9531 analyzed_executable->backward_branch_quota = backward_branch_quota; 9532 analyzed_executable->begin_scope = scope; 9533 ZigType *result_type = ir_analyze(codegen, ir_executable, analyzed_executable, expected_type, node); 9534 if (type_is_invalid(result_type)) 9535 return codegen->invalid_instruction; 9536 9537 if (codegen->verbose_ir) { 9538 fprintf(stderr, "{ // (analyzed)\n"); 9539 ir_print(codegen, stderr, analyzed_executable, 4); 9540 fprintf(stderr, "}\n"); 9541 } 9542 9543 return ir_exec_const_result(codegen, analyzed_executable); 9544 } 9545 9546 static ZigType *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value) { 9547 if (type_is_invalid(type_value->value.type)) 9548 return ira->codegen->builtin_types.entry_invalid; 9549 9550 if (type_value->value.type->id != ZigTypeIdMetaType) { 9551 ir_add_error(ira, type_value, 9552 buf_sprintf("expected type 'type', found '%s'", buf_ptr(&type_value->value.type->name))); 9553 return ira->codegen->builtin_types.entry_invalid; 9554 } 9555 9556 ConstExprValue *const_val = ir_resolve_const(ira, type_value, UndefBad); 9557 if (!const_val) 9558 return ira->codegen->builtin_types.entry_invalid; 9559 9560 assert(const_val->data.x_type != nullptr); 9561 return const_val->data.x_type; 9562 } 9563 9564 static ZigFn *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { 9565 if (fn_value == ira->codegen->invalid_instruction) 9566 return nullptr; 9567 9568 if (type_is_invalid(fn_value->value.type)) 9569 return nullptr; 9570 9571 if (fn_value->value.type->id != ZigTypeIdFn) { 9572 ir_add_error_node(ira, fn_value->source_node, 9573 buf_sprintf("expected function type, found '%s'", buf_ptr(&fn_value->value.type->name))); 9574 return nullptr; 9575 } 9576 9577 ConstExprValue *const_val = ir_resolve_const(ira, fn_value, UndefBad); 9578 if (!const_val) 9579 return nullptr; 9580 9581 assert(const_val->data.x_ptr.special == ConstPtrSpecialFunction); 9582 return const_val->data.x_ptr.data.fn.fn_entry; 9583 } 9584 9585 static IrInstruction *ir_analyze_maybe_wrap(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { 9586 assert(wanted_type->id == ZigTypeIdOptional); 9587 9588 if (instr_is_comptime(value)) { 9589 ZigType *payload_type = wanted_type->data.maybe.child_type; 9590 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); 9591 if (type_is_invalid(casted_payload->value.type)) 9592 return ira->codegen->invalid_instruction; 9593 9594 ConstExprValue *val = ir_resolve_const(ira, casted_payload, UndefOk); 9595 if (!val) 9596 return ira->codegen->invalid_instruction; 9597 9598 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 9599 source_instr->scope, source_instr->source_node); 9600 const_instruction->base.value.special = ConstValSpecialStatic; 9601 if (get_codegen_ptr_type(wanted_type) != nullptr) { 9602 copy_const_val(&const_instruction->base.value, val, val->data.x_ptr.mut == ConstPtrMutComptimeConst); 9603 } else { 9604 const_instruction->base.value.data.x_optional = val; 9605 } 9606 const_instruction->base.value.type = wanted_type; 9607 return &const_instruction->base; 9608 } 9609 9610 IrInstruction *result = ir_build_maybe_wrap(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 9611 result->value.type = wanted_type; 9612 result->value.data.rh_maybe = RuntimeHintOptionalNonNull; 9613 ir_add_alloca(ira, result, wanted_type); 9614 return result; 9615 } 9616 9617 static IrInstruction *ir_analyze_err_wrap_payload(IrAnalyze *ira, IrInstruction *source_instr, 9618 IrInstruction *value, ZigType *wanted_type) 9619 { 9620 assert(wanted_type->id == ZigTypeIdErrorUnion); 9621 9622 if (instr_is_comptime(value)) { 9623 ZigType *payload_type = wanted_type->data.error_union.payload_type; 9624 IrInstruction *casted_payload = ir_implicit_cast(ira, value, payload_type); 9625 if (type_is_invalid(casted_payload->value.type)) 9626 return ira->codegen->invalid_instruction; 9627 9628 ConstExprValue *val = ir_resolve_const(ira, casted_payload, UndefBad); 9629 if (!val) 9630 return ira->codegen->invalid_instruction; 9631 9632 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 9633 source_instr->scope, source_instr->source_node); 9634 const_instruction->base.value.type = wanted_type; 9635 const_instruction->base.value.special = ConstValSpecialStatic; 9636 const_instruction->base.value.data.x_err_union.err = nullptr; 9637 const_instruction->base.value.data.x_err_union.payload = val; 9638 return &const_instruction->base; 9639 } 9640 9641 IrInstruction *result = ir_build_err_wrap_payload(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 9642 result->value.type = wanted_type; 9643 result->value.data.rh_error_union = RuntimeHintErrorUnionNonError; 9644 ir_add_alloca(ira, result, wanted_type); 9645 return result; 9646 } 9647 9648 static IrInstruction *ir_analyze_err_set_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, 9649 ZigType *wanted_type) 9650 { 9651 assert(value->value.type->id == ZigTypeIdErrorSet); 9652 assert(wanted_type->id == ZigTypeIdErrorSet); 9653 9654 if (instr_is_comptime(value)) { 9655 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 9656 if (!val) 9657 return ira->codegen->invalid_instruction; 9658 9659 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 9660 return ira->codegen->invalid_instruction; 9661 } 9662 if (!type_is_global_error_set(wanted_type)) { 9663 bool subset = false; 9664 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 9665 if (wanted_type->data.error_set.errors[i]->value == val->data.x_err_set->value) { 9666 subset = true; 9667 break; 9668 } 9669 } 9670 if (!subset) { 9671 ir_add_error(ira, source_instr, 9672 buf_sprintf("error.%s not a member of error set '%s'", 9673 buf_ptr(&val->data.x_err_set->name), buf_ptr(&wanted_type->name))); 9674 return ira->codegen->invalid_instruction; 9675 } 9676 } 9677 9678 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 9679 source_instr->scope, source_instr->source_node); 9680 const_instruction->base.value.type = wanted_type; 9681 const_instruction->base.value.special = ConstValSpecialStatic; 9682 const_instruction->base.value.data.x_err_set = val->data.x_err_set; 9683 return &const_instruction->base; 9684 } 9685 9686 IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, CastOpErrSet); 9687 result->value.type = wanted_type; 9688 return result; 9689 } 9690 9691 static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { 9692 assert(wanted_type->id == ZigTypeIdErrorUnion); 9693 9694 IrInstruction *casted_value = ir_implicit_cast(ira, value, wanted_type->data.error_union.err_set_type); 9695 9696 if (instr_is_comptime(casted_value)) { 9697 ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad); 9698 if (!val) 9699 return ira->codegen->invalid_instruction; 9700 9701 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 9702 source_instr->scope, source_instr->source_node); 9703 const_instruction->base.value.type = wanted_type; 9704 const_instruction->base.value.special = ConstValSpecialStatic; 9705 const_instruction->base.value.data.x_err_union.err = val->data.x_err_set; 9706 const_instruction->base.value.data.x_err_union.payload = nullptr; 9707 return &const_instruction->base; 9708 } 9709 9710 IrInstruction *result = ir_build_err_wrap_code(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 9711 result->value.type = wanted_type; 9712 result->value.data.rh_error_union = RuntimeHintErrorUnionError; 9713 ir_add_alloca(ira, result, wanted_type); 9714 return result; 9715 } 9716 9717 static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, ZigType *wanted_type) { 9718 assert(wanted_type->id == ZigTypeIdOptional); 9719 assert(instr_is_comptime(value)); 9720 9721 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 9722 assert(val); 9723 9724 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, source_instr->scope, source_instr->source_node); 9725 const_instruction->base.value.special = ConstValSpecialStatic; 9726 if (get_codegen_ptr_type(wanted_type) != nullptr) { 9727 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 9728 const_instruction->base.value.data.x_ptr.data.hard_coded_addr.addr = 0; 9729 } else { 9730 const_instruction->base.value.data.x_optional = nullptr; 9731 } 9732 const_instruction->base.value.type = wanted_type; 9733 return &const_instruction->base; 9734 } 9735 9736 static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *value, 9737 bool is_const, bool is_volatile) 9738 { 9739 Error err; 9740 9741 if (type_is_invalid(value->value.type)) 9742 return ira->codegen->invalid_instruction; 9743 9744 if ((err = type_resolve(ira->codegen, value->value.type, ResolveStatusZeroBitsKnown))) 9745 return ira->codegen->invalid_instruction; 9746 9747 if (instr_is_comptime(value)) { 9748 ConstExprValue *val = ir_resolve_const(ira, value, UndefOk); 9749 if (!val) 9750 return ira->codegen->invalid_instruction; 9751 return ir_get_const_ptr(ira, source_instruction, val, value->value.type, 9752 ConstPtrMutComptimeConst, is_const, is_volatile, 0); 9753 } 9754 9755 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type, 9756 is_const, is_volatile, PtrLenSingle, 0, 0, 0); 9757 IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope, 9758 source_instruction->source_node, value, is_const, is_volatile); 9759 new_instruction->value.type = ptr_type; 9760 new_instruction->value.data.rh_ptr = RuntimeHintPtrStack; 9761 if (type_has_bits(ptr_type)) { 9762 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 9763 assert(fn_entry); 9764 fn_entry->alloca_list.append(new_instruction); 9765 } 9766 return new_instruction; 9767 } 9768 9769 static IrInstruction *ir_analyze_array_to_slice(IrAnalyze *ira, IrInstruction *source_instr, 9770 IrInstruction *array_arg, ZigType *wanted_type) 9771 { 9772 assert(is_slice(wanted_type)); 9773 // In this function we honor the const-ness of wanted_type, because 9774 // we may be casting [0]T to []const T which is perfectly valid. 9775 9776 IrInstruction *array_ptr = nullptr; 9777 IrInstruction *array; 9778 if (array_arg->value.type->id == ZigTypeIdPointer) { 9779 array = ir_get_deref(ira, source_instr, array_arg); 9780 array_ptr = array_arg; 9781 } else { 9782 array = array_arg; 9783 } 9784 ZigType *array_type = array->value.type; 9785 assert(array_type->id == ZigTypeIdArray); 9786 9787 if (instr_is_comptime(array)) { 9788 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9789 source_instr->source_node, wanted_type); 9790 init_const_slice(ira->codegen, &result->value, &array->value, 0, array_type->data.array.len, true); 9791 result->value.type = wanted_type; 9792 return result; 9793 } 9794 9795 IrInstruction *start = ir_create_const(&ira->new_irb, source_instr->scope, 9796 source_instr->source_node, ira->codegen->builtin_types.entry_usize); 9797 init_const_usize(ira->codegen, &start->value, 0); 9798 9799 IrInstruction *end = ir_create_const(&ira->new_irb, source_instr->scope, 9800 source_instr->source_node, ira->codegen->builtin_types.entry_usize); 9801 init_const_usize(ira->codegen, &end->value, array_type->data.array.len); 9802 9803 if (!array_ptr) array_ptr = ir_get_ref(ira, source_instr, array, true, false); 9804 9805 IrInstruction *result = ir_build_slice(&ira->new_irb, source_instr->scope, 9806 source_instr->source_node, array_ptr, start, end, false); 9807 result->value.type = wanted_type; 9808 result->value.data.rh_slice.id = RuntimeHintSliceIdLen; 9809 result->value.data.rh_slice.len = array_type->data.array.len; 9810 ir_add_alloca(ira, result, result->value.type); 9811 9812 return result; 9813 } 9814 9815 static IrInstruction *ir_analyze_enum_to_int(IrAnalyze *ira, IrInstruction *source_instr, 9816 IrInstruction *target, ZigType *wanted_type) 9817 { 9818 Error err; 9819 assert(wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdComptimeInt); 9820 9821 ZigType *actual_type = target->value.type; 9822 if ((err = ensure_complete_type(ira->codegen, actual_type))) 9823 return ira->codegen->invalid_instruction; 9824 9825 if (wanted_type != actual_type->data.enumeration.tag_int_type) { 9826 ir_add_error(ira, source_instr, 9827 buf_sprintf("enum to integer cast to '%s' instead of its tag type, '%s'", 9828 buf_ptr(&wanted_type->name), 9829 buf_ptr(&actual_type->data.enumeration.tag_int_type->name))); 9830 return ira->codegen->invalid_instruction; 9831 } 9832 9833 assert(actual_type->id == ZigTypeIdEnum); 9834 9835 if (instr_is_comptime(target)) { 9836 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 9837 if (!val) 9838 return ira->codegen->invalid_instruction; 9839 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9840 source_instr->source_node, wanted_type); 9841 init_const_bigint(&result->value, wanted_type, &val->data.x_enum_tag); 9842 return result; 9843 } 9844 9845 // If there is only one possible tag, then we know at comptime what it is. 9846 if (actual_type->data.enumeration.layout == ContainerLayoutAuto && 9847 actual_type->data.enumeration.src_field_count == 1) 9848 { 9849 assert(wanted_type== ira->codegen->builtin_types.entry_num_lit_int); 9850 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9851 source_instr->source_node, wanted_type); 9852 init_const_bigint(&result->value, wanted_type, 9853 &actual_type->data.enumeration.fields[0].value); 9854 return result; 9855 } 9856 9857 IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, 9858 source_instr->source_node, target); 9859 result->value.type = wanted_type; 9860 return result; 9861 } 9862 9863 static IrInstruction *ir_analyze_union_to_tag(IrAnalyze *ira, IrInstruction *source_instr, 9864 IrInstruction *target, ZigType *wanted_type) 9865 { 9866 assert(target->value.type->id == ZigTypeIdUnion); 9867 assert(wanted_type->id == ZigTypeIdEnum); 9868 assert(wanted_type == target->value.type->data.unionation.tag_type); 9869 9870 if (instr_is_comptime(target)) { 9871 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 9872 if (!val) 9873 return ira->codegen->invalid_instruction; 9874 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9875 source_instr->source_node, wanted_type); 9876 result->value.special = ConstValSpecialStatic; 9877 result->value.type = wanted_type; 9878 bigint_init_bigint(&result->value.data.x_enum_tag, &val->data.x_union.tag); 9879 return result; 9880 } 9881 9882 // If there is only 1 possible tag, then we know at comptime what it is. 9883 if (wanted_type->data.enumeration.layout == ContainerLayoutAuto && 9884 wanted_type->data.enumeration.src_field_count == 1) 9885 { 9886 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9887 source_instr->source_node, wanted_type); 9888 result->value.special = ConstValSpecialStatic; 9889 result->value.type = wanted_type; 9890 TypeEnumField *enum_field = target->value.type->data.unionation.fields[0].enum_field; 9891 bigint_init_bigint(&result->value.data.x_enum_tag, &enum_field->value); 9892 return result; 9893 } 9894 9895 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, 9896 source_instr->source_node, target); 9897 result->value.type = wanted_type; 9898 return result; 9899 } 9900 9901 static IrInstruction *ir_analyze_undefined_to_anything(IrAnalyze *ira, IrInstruction *source_instr, 9902 IrInstruction *target, ZigType *wanted_type) 9903 { 9904 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9905 source_instr->source_node, wanted_type); 9906 init_const_undefined(ira->codegen, &result->value); 9907 return result; 9908 } 9909 9910 static IrInstruction *ir_analyze_enum_to_union(IrAnalyze *ira, IrInstruction *source_instr, 9911 IrInstruction *target, ZigType *wanted_type) 9912 { 9913 Error err; 9914 assert(wanted_type->id == ZigTypeIdUnion); 9915 assert(target->value.type->id == ZigTypeIdEnum); 9916 9917 if (instr_is_comptime(target)) { 9918 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 9919 if (!val) 9920 return ira->codegen->invalid_instruction; 9921 TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag); 9922 assert(union_field != nullptr); 9923 if ((err = type_resolve(ira->codegen, union_field->type_entry, ResolveStatusZeroBitsKnown))) 9924 return ira->codegen->invalid_instruction; 9925 if (type_has_bits(union_field->type_entry)) { 9926 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at( 9927 union_field->enum_field->decl_index); 9928 ErrorMsg *msg = ir_add_error(ira, source_instr, 9929 buf_sprintf("cast to union '%s' must initialize '%s' field '%s'", 9930 buf_ptr(&wanted_type->name), 9931 buf_ptr(&union_field->type_entry->name), 9932 buf_ptr(union_field->name))); 9933 add_error_note(ira->codegen, msg, field_node, 9934 buf_sprintf("field '%s' declared here", buf_ptr(union_field->name))); 9935 return ira->codegen->invalid_instruction; 9936 } 9937 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9938 source_instr->source_node, wanted_type); 9939 result->value.special = ConstValSpecialStatic; 9940 result->value.type = wanted_type; 9941 bigint_init_bigint(&result->value.data.x_union.tag, &val->data.x_enum_tag); 9942 return result; 9943 } 9944 9945 // if the union has all fields 0 bits, we can do it 9946 // and in fact it's a noop cast because the union value is just the enum value 9947 if (wanted_type->data.unionation.gen_field_count == 0) { 9948 IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, wanted_type, target, CastOpNoop); 9949 result->value.type = wanted_type; 9950 return result; 9951 } 9952 9953 ErrorMsg *msg = ir_add_error(ira, source_instr, 9954 buf_sprintf("runtime cast to union '%s' which has non-void fields", 9955 buf_ptr(&wanted_type->name))); 9956 for (uint32_t i = 0; i < wanted_type->data.unionation.src_field_count; i += 1) { 9957 TypeUnionField *union_field = &wanted_type->data.unionation.fields[i]; 9958 if (type_has_bits(union_field->type_entry)) { 9959 AstNode *field_node = wanted_type->data.unionation.decl_node->data.container_decl.fields.at(i); 9960 add_error_note(ira->codegen, msg, field_node, 9961 buf_sprintf("field '%s' has type '%s'", 9962 buf_ptr(union_field->name), 9963 buf_ptr(&union_field->type_entry->name))); 9964 } 9965 } 9966 return ira->codegen->invalid_instruction; 9967 } 9968 9969 static IrInstruction *ir_analyze_widen_or_shorten(IrAnalyze *ira, IrInstruction *source_instr, 9970 IrInstruction *target, ZigType *wanted_type) 9971 { 9972 assert(wanted_type->id == ZigTypeIdInt || wanted_type->id == ZigTypeIdFloat); 9973 9974 if (instr_is_comptime(target)) { 9975 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 9976 if (!val) 9977 return ira->codegen->invalid_instruction; 9978 if (wanted_type->id == ZigTypeIdInt) { 9979 if (bigint_cmp_zero(&val->data.x_bigint) == CmpLT && !wanted_type->data.integral.is_signed) { 9980 ir_add_error(ira, source_instr, 9981 buf_sprintf("attempt to cast negative value to unsigned integer")); 9982 return ira->codegen->invalid_instruction; 9983 } 9984 if (!bigint_fits_in_bits(&val->data.x_bigint, wanted_type->data.integral.bit_count, 9985 wanted_type->data.integral.is_signed)) 9986 { 9987 ir_add_error(ira, source_instr, 9988 buf_sprintf("cast from '%s' to '%s' truncates bits", 9989 buf_ptr(&target->value.type->name), buf_ptr(&wanted_type->name))); 9990 return ira->codegen->invalid_instruction; 9991 } 9992 } 9993 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 9994 source_instr->source_node, wanted_type); 9995 result->value.type = wanted_type; 9996 if (wanted_type->id == ZigTypeIdInt) { 9997 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); 9998 } else { 9999 float_init_float(&result->value, val); 10000 } 10001 return result; 10002 } 10003 10004 IrInstruction *result = ir_build_widen_or_shorten(&ira->new_irb, source_instr->scope, 10005 source_instr->source_node, target); 10006 result->value.type = wanted_type; 10007 return result; 10008 } 10009 10010 static IrInstruction *ir_analyze_int_to_enum(IrAnalyze *ira, IrInstruction *source_instr, 10011 IrInstruction *target, ZigType *wanted_type) 10012 { 10013 Error err; 10014 assert(wanted_type->id == ZigTypeIdEnum); 10015 10016 ZigType *actual_type = target->value.type; 10017 10018 if ((err = ensure_complete_type(ira->codegen, wanted_type))) 10019 return ira->codegen->invalid_instruction; 10020 10021 if (actual_type != wanted_type->data.enumeration.tag_int_type) { 10022 ir_add_error(ira, source_instr, 10023 buf_sprintf("integer to enum cast from '%s' instead of its tag type, '%s'", 10024 buf_ptr(&actual_type->name), 10025 buf_ptr(&wanted_type->data.enumeration.tag_int_type->name))); 10026 return ira->codegen->invalid_instruction; 10027 } 10028 10029 assert(actual_type->id == ZigTypeIdInt); 10030 10031 if (instr_is_comptime(target)) { 10032 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10033 if (!val) 10034 return ira->codegen->invalid_instruction; 10035 10036 TypeEnumField *field = find_enum_field_by_tag(wanted_type, &val->data.x_bigint); 10037 if (field == nullptr) { 10038 Buf *val_buf = buf_alloc(); 10039 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 10040 ErrorMsg *msg = ir_add_error(ira, source_instr, 10041 buf_sprintf("enum '%s' has no tag matching integer value %s", 10042 buf_ptr(&wanted_type->name), buf_ptr(val_buf))); 10043 add_error_note(ira->codegen, msg, wanted_type->data.enumeration.decl_node, 10044 buf_sprintf("'%s' declared here", buf_ptr(&wanted_type->name))); 10045 return ira->codegen->invalid_instruction; 10046 } 10047 10048 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10049 source_instr->source_node, wanted_type); 10050 bigint_init_bigint(&result->value.data.x_enum_tag, &val->data.x_bigint); 10051 return result; 10052 } 10053 10054 IrInstruction *result = ir_build_int_to_enum(&ira->new_irb, source_instr->scope, 10055 source_instr->source_node, nullptr, target); 10056 result->value.type = wanted_type; 10057 return result; 10058 } 10059 10060 static IrInstruction *ir_analyze_number_to_literal(IrAnalyze *ira, IrInstruction *source_instr, 10061 IrInstruction *target, ZigType *wanted_type) 10062 { 10063 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10064 if (!val) 10065 return ira->codegen->invalid_instruction; 10066 10067 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10068 source_instr->source_node, wanted_type); 10069 if (wanted_type->id == ZigTypeIdComptimeFloat) { 10070 float_init_float(&result->value, val); 10071 } else if (wanted_type->id == ZigTypeIdComptimeInt) { 10072 bigint_init_bigint(&result->value.data.x_bigint, &val->data.x_bigint); 10073 } else { 10074 zig_unreachable(); 10075 } 10076 return result; 10077 } 10078 10079 static IrInstruction *ir_analyze_int_to_err(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 10080 ZigType *wanted_type) 10081 { 10082 assert(target->value.type->id == ZigTypeIdInt); 10083 assert(!target->value.type->data.integral.is_signed); 10084 assert(wanted_type->id == ZigTypeIdErrorSet); 10085 10086 if (instr_is_comptime(target)) { 10087 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10088 if (!val) 10089 return ira->codegen->invalid_instruction; 10090 10091 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10092 source_instr->source_node, wanted_type); 10093 10094 if (!resolve_inferred_error_set(ira->codegen, wanted_type, source_instr->source_node)) { 10095 return ira->codegen->invalid_instruction; 10096 } 10097 10098 if (type_is_global_error_set(wanted_type)) { 10099 BigInt err_count; 10100 bigint_init_unsigned(&err_count, ira->codegen->errors_by_index.length); 10101 10102 if (bigint_cmp_zero(&val->data.x_bigint) == CmpEQ || bigint_cmp(&val->data.x_bigint, &err_count) != CmpLT) { 10103 Buf *val_buf = buf_alloc(); 10104 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 10105 ir_add_error(ira, source_instr, 10106 buf_sprintf("integer value %s represents no error", buf_ptr(val_buf))); 10107 return ira->codegen->invalid_instruction; 10108 } 10109 10110 size_t index = bigint_as_unsigned(&val->data.x_bigint); 10111 result->value.data.x_err_set = ira->codegen->errors_by_index.at(index); 10112 return result; 10113 } else { 10114 ErrorTableEntry *err = nullptr; 10115 BigInt err_int; 10116 10117 for (uint32_t i = 0, count = wanted_type->data.error_set.err_count; i < count; i += 1) { 10118 ErrorTableEntry *this_err = wanted_type->data.error_set.errors[i]; 10119 bigint_init_unsigned(&err_int, this_err->value); 10120 if (bigint_cmp(&val->data.x_bigint, &err_int) == CmpEQ) { 10121 err = this_err; 10122 break; 10123 } 10124 } 10125 10126 if (err == nullptr) { 10127 Buf *val_buf = buf_alloc(); 10128 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 10129 ir_add_error(ira, source_instr, 10130 buf_sprintf("integer value %s represents no error in '%s'", buf_ptr(val_buf), buf_ptr(&wanted_type->name))); 10131 return ira->codegen->invalid_instruction; 10132 } 10133 10134 result->value.data.x_err_set = err; 10135 return result; 10136 } 10137 } 10138 10139 IrInstruction *result = ir_build_int_to_err(&ira->new_irb, source_instr->scope, source_instr->source_node, target); 10140 result->value.type = wanted_type; 10141 return result; 10142 } 10143 10144 static IrInstruction *ir_analyze_err_to_int(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 10145 ZigType *wanted_type) 10146 { 10147 assert(wanted_type->id == ZigTypeIdInt); 10148 10149 ZigType *err_type = target->value.type; 10150 10151 if (instr_is_comptime(target)) { 10152 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10153 if (!val) 10154 return ira->codegen->invalid_instruction; 10155 10156 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10157 source_instr->source_node, wanted_type); 10158 10159 ErrorTableEntry *err; 10160 if (err_type->id == ZigTypeIdErrorUnion) { 10161 err = val->data.x_err_union.err; 10162 } else if (err_type->id == ZigTypeIdErrorSet) { 10163 err = val->data.x_err_set; 10164 } else { 10165 zig_unreachable(); 10166 } 10167 result->value.type = wanted_type; 10168 uint64_t err_value = err ? err->value : 0; 10169 bigint_init_unsigned(&result->value.data.x_bigint, err_value); 10170 10171 if (!bigint_fits_in_bits(&result->value.data.x_bigint, 10172 wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) 10173 { 10174 ir_add_error_node(ira, source_instr->source_node, 10175 buf_sprintf("error code '%s' does not fit in '%s'", 10176 buf_ptr(&err->name), buf_ptr(&wanted_type->name))); 10177 return ira->codegen->invalid_instruction; 10178 } 10179 10180 return result; 10181 } 10182 10183 ZigType *err_set_type; 10184 if (err_type->id == ZigTypeIdErrorUnion) { 10185 err_set_type = err_type->data.error_union.err_set_type; 10186 } else if (err_type->id == ZigTypeIdErrorSet) { 10187 err_set_type = err_type; 10188 } else { 10189 zig_unreachable(); 10190 } 10191 if (!type_is_global_error_set(err_set_type)) { 10192 if (!resolve_inferred_error_set(ira->codegen, err_set_type, source_instr->source_node)) { 10193 return ira->codegen->invalid_instruction; 10194 } 10195 if (err_set_type->data.error_set.err_count == 0) { 10196 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10197 source_instr->source_node, wanted_type); 10198 result->value.type = wanted_type; 10199 bigint_init_unsigned(&result->value.data.x_bigint, 0); 10200 return result; 10201 } else if (err_set_type->data.error_set.err_count == 1) { 10202 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, 10203 source_instr->source_node, wanted_type); 10204 result->value.type = wanted_type; 10205 ErrorTableEntry *err = err_set_type->data.error_set.errors[0]; 10206 bigint_init_unsigned(&result->value.data.x_bigint, err->value); 10207 return result; 10208 } 10209 } 10210 10211 BigInt bn; 10212 bigint_init_unsigned(&bn, ira->codegen->errors_by_index.length); 10213 if (!bigint_fits_in_bits(&bn, wanted_type->data.integral.bit_count, wanted_type->data.integral.is_signed)) { 10214 ir_add_error_node(ira, source_instr->source_node, 10215 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name))); 10216 return ira->codegen->invalid_instruction; 10217 } 10218 10219 IrInstruction *result = ir_build_err_to_int(&ira->new_irb, source_instr->scope, source_instr->source_node, target); 10220 result->value.type = wanted_type; 10221 return result; 10222 } 10223 10224 static IrInstruction *ir_analyze_ptr_to_array(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *target, 10225 ZigType *wanted_type) 10226 { 10227 assert(wanted_type->id == ZigTypeIdPointer); 10228 Error err; 10229 if ((err = type_resolve(ira->codegen, target->value.type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 10230 return ira->codegen->invalid_instruction; 10231 wanted_type = adjust_ptr_align(ira->codegen, wanted_type, get_ptr_align(ira->codegen, target->value.type)); 10232 ZigType *array_type = wanted_type->data.pointer.child_type; 10233 assert(array_type->id == ZigTypeIdArray); 10234 assert(array_type->data.array.len == 1); 10235 10236 if (instr_is_comptime(target)) { 10237 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 10238 if (!val) 10239 return ira->codegen->invalid_instruction; 10240 10241 assert(val->type->id == ZigTypeIdPointer); 10242 ConstExprValue *pointee = ir_const_ptr_pointee(ira, val, source_instr->source_node); 10243 if (pointee == nullptr) 10244 return ira->codegen->invalid_instruction; 10245 if (pointee->special != ConstValSpecialRuntime) { 10246 ConstExprValue *array_val = create_const_vals(1); 10247 array_val->special = ConstValSpecialStatic; 10248 array_val->type = array_type; 10249 array_val->data.x_array.special = ConstArraySpecialNone; 10250 array_val->data.x_array.data.s_none.elements = pointee; 10251 array_val->data.x_array.data.s_none.parent.id = ConstParentIdScalar; 10252 array_val->data.x_array.data.s_none.parent.data.p_scalar.scalar_val = pointee; 10253 10254 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 10255 source_instr->scope, source_instr->source_node); 10256 const_instruction->base.value.type = wanted_type; 10257 const_instruction->base.value.special = ConstValSpecialStatic; 10258 const_instruction->base.value.data.x_ptr.special = ConstPtrSpecialRef; 10259 const_instruction->base.value.data.x_ptr.data.ref.pointee = array_val; 10260 const_instruction->base.value.data.x_ptr.mut = val->data.x_ptr.mut; 10261 return &const_instruction->base; 10262 } 10263 } 10264 10265 // pointer to array and pointer to single item are represented the same way at runtime 10266 IrInstruction *result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, 10267 wanted_type, target, CastOpBitCast); 10268 result->value.type = wanted_type; 10269 return result; 10270 } 10271 10272 static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCastOnly *cast_result, 10273 ErrorMsg *parent_msg) 10274 { 10275 switch (cast_result->id) { 10276 case ConstCastResultIdOk: 10277 zig_unreachable(); 10278 case ConstCastResultIdInvalid: 10279 zig_unreachable(); 10280 case ConstCastResultIdOptionalChild: { 10281 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 10282 buf_sprintf("optional type child '%s' cannot cast into optional type child '%s'", 10283 buf_ptr(&cast_result->data.optional->actual_child->name), 10284 buf_ptr(&cast_result->data.optional->wanted_child->name))); 10285 report_recursive_error(ira, source_node, &cast_result->data.optional->child, msg); 10286 break; 10287 } 10288 case ConstCastResultIdErrorUnionErrorSet: { 10289 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 10290 buf_sprintf("error set '%s' cannot cast into error set '%s'", 10291 buf_ptr(&cast_result->data.error_union_error_set->actual_err_set->name), 10292 buf_ptr(&cast_result->data.error_union_error_set->wanted_err_set->name))); 10293 report_recursive_error(ira, source_node, &cast_result->data.error_union_error_set->child, msg); 10294 break; 10295 } 10296 case ConstCastResultIdErrSet: { 10297 ZigList<ErrorTableEntry *> *missing_errors = &cast_result->data.error_set_mismatch->missing_errors; 10298 for (size_t i = 0; i < missing_errors->length; i += 1) { 10299 ErrorTableEntry *error_entry = missing_errors->at(i); 10300 add_error_note(ira->codegen, parent_msg, error_entry->decl_node, 10301 buf_sprintf("'error.%s' not a member of destination error set", buf_ptr(&error_entry->name))); 10302 } 10303 break; 10304 } 10305 case ConstCastResultIdErrSetGlobal: { 10306 add_error_note(ira->codegen, parent_msg, source_node, 10307 buf_sprintf("cannot cast global error set into smaller set")); 10308 break; 10309 } 10310 case ConstCastResultIdPointerChild: { 10311 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 10312 buf_sprintf("pointer type child '%s' cannot cast into pointer type child '%s'", 10313 buf_ptr(&cast_result->data.pointer_mismatch->actual_child->name), 10314 buf_ptr(&cast_result->data.pointer_mismatch->wanted_child->name))); 10315 report_recursive_error(ira, source_node, &cast_result->data.pointer_mismatch->child, msg); 10316 break; 10317 } 10318 case ConstCastResultIdSliceChild: { 10319 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 10320 buf_sprintf("slice type child '%s' cannot cast into slice type child '%s'", 10321 buf_ptr(&cast_result->data.slice_mismatch->actual_child->name), 10322 buf_ptr(&cast_result->data.slice_mismatch->wanted_child->name))); 10323 report_recursive_error(ira, source_node, &cast_result->data.slice_mismatch->child, msg); 10324 break; 10325 } 10326 case ConstCastResultIdErrorUnionPayload: { 10327 ErrorMsg *msg = add_error_note(ira->codegen, parent_msg, source_node, 10328 buf_sprintf("error union payload '%s' cannot cast into error union payload '%s'", 10329 buf_ptr(&cast_result->data.error_union_payload->actual_payload->name), 10330 buf_ptr(&cast_result->data.error_union_payload->wanted_payload->name))); 10331 report_recursive_error(ira, source_node, &cast_result->data.error_union_payload->child, msg); 10332 break; 10333 } 10334 case ConstCastResultIdType: { 10335 AstNode *wanted_decl_node = type_decl_node(cast_result->data.type_mismatch->wanted_type); 10336 AstNode *actual_decl_node = type_decl_node(cast_result->data.type_mismatch->actual_type); 10337 if (wanted_decl_node != nullptr) { 10338 add_error_note(ira->codegen, parent_msg, wanted_decl_node, 10339 buf_sprintf("%s declared here", 10340 buf_ptr(&cast_result->data.type_mismatch->wanted_type->name))); 10341 } 10342 if (actual_decl_node != nullptr) { 10343 add_error_note(ira->codegen, parent_msg, actual_decl_node, 10344 buf_sprintf("%s declared here", 10345 buf_ptr(&cast_result->data.type_mismatch->actual_type->name))); 10346 } 10347 break; 10348 } 10349 case ConstCastResultIdFnAlign: // TODO 10350 case ConstCastResultIdFnCC: // TODO 10351 case ConstCastResultIdFnVarArgs: // TODO 10352 case ConstCastResultIdFnIsGeneric: // TODO 10353 case ConstCastResultIdFnReturnType: // TODO 10354 case ConstCastResultIdFnArgCount: // TODO 10355 case ConstCastResultIdFnGenericArgCount: // TODO 10356 case ConstCastResultIdFnArg: // TODO 10357 case ConstCastResultIdFnArgNoAlias: // TODO 10358 case ConstCastResultIdUnresolvedInferredErrSet: // TODO 10359 case ConstCastResultIdAsyncAllocatorType: // TODO 10360 case ConstCastResultIdNullWrapPtr: // TODO 10361 break; 10362 } 10363 } 10364 10365 static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_instr, 10366 ZigType *wanted_type, IrInstruction *value) 10367 { 10368 Error err; 10369 ZigType *actual_type = value->value.type; 10370 AstNode *source_node = source_instr->source_node; 10371 10372 if (type_is_invalid(wanted_type) || type_is_invalid(actual_type)) { 10373 return ira->codegen->invalid_instruction; 10374 } 10375 10376 // perfect match or non-const to const 10377 ConstCastOnly const_cast_result = types_match_const_cast_only(ira, wanted_type, actual_type, 10378 source_node, false); 10379 if (const_cast_result.id == ConstCastResultIdInvalid) 10380 return ira->codegen->invalid_instruction; 10381 if (const_cast_result.id == ConstCastResultIdOk) { 10382 return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); 10383 } 10384 10385 // widening conversion 10386 if (wanted_type->id == ZigTypeIdInt && 10387 actual_type->id == ZigTypeIdInt && 10388 wanted_type->data.integral.is_signed == actual_type->data.integral.is_signed && 10389 wanted_type->data.integral.bit_count >= actual_type->data.integral.bit_count) 10390 { 10391 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 10392 } 10393 10394 // small enough unsigned ints can get casted to large enough signed ints 10395 if (wanted_type->id == ZigTypeIdInt && wanted_type->data.integral.is_signed && 10396 actual_type->id == ZigTypeIdInt && !actual_type->data.integral.is_signed && 10397 wanted_type->data.integral.bit_count > actual_type->data.integral.bit_count) 10398 { 10399 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 10400 } 10401 10402 // float widening conversion 10403 if (wanted_type->id == ZigTypeIdFloat && 10404 actual_type->id == ZigTypeIdFloat && 10405 wanted_type->data.floating.bit_count >= actual_type->data.floating.bit_count) 10406 { 10407 return ir_analyze_widen_or_shorten(ira, source_instr, value, wanted_type); 10408 } 10409 10410 10411 // cast from [N]T to []const T 10412 if (is_slice(wanted_type) && actual_type->id == ZigTypeIdArray) { 10413 ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 10414 assert(ptr_type->id == ZigTypeIdPointer); 10415 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 10416 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 10417 source_node, false).id == ConstCastResultIdOk) 10418 { 10419 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type); 10420 } 10421 } 10422 10423 // cast from *const [N]T to []const T 10424 if (is_slice(wanted_type) && 10425 actual_type->id == ZigTypeIdPointer && 10426 actual_type->data.pointer.is_const && 10427 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 10428 { 10429 ZigType *ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 10430 assert(ptr_type->id == ZigTypeIdPointer); 10431 10432 ZigType *array_type = actual_type->data.pointer.child_type; 10433 10434 if ((ptr_type->data.pointer.is_const || array_type->data.array.len == 0) && 10435 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, array_type->data.array.child_type, 10436 source_node, false).id == ConstCastResultIdOk) 10437 { 10438 return ir_analyze_array_to_slice(ira, source_instr, value, wanted_type); 10439 } 10440 } 10441 10442 // cast from [N]T to ?[]const T 10443 if (wanted_type->id == ZigTypeIdOptional && 10444 is_slice(wanted_type->data.maybe.child_type) && 10445 actual_type->id == ZigTypeIdArray) 10446 { 10447 ZigType *ptr_type = 10448 wanted_type->data.maybe.child_type->data.structure.fields[slice_ptr_index].type_entry; 10449 assert(ptr_type->id == ZigTypeIdPointer); 10450 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 10451 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 10452 source_node, false).id == ConstCastResultIdOk) 10453 { 10454 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.maybe.child_type, value); 10455 if (type_is_invalid(cast1->value.type)) 10456 return ira->codegen->invalid_instruction; 10457 10458 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 10459 if (type_is_invalid(cast2->value.type)) 10460 return ira->codegen->invalid_instruction; 10461 10462 return cast2; 10463 } 10464 } 10465 10466 // *[N]T to [*]T 10467 if (wanted_type->id == ZigTypeIdPointer && 10468 wanted_type->data.pointer.ptr_len == PtrLenUnknown && 10469 actual_type->id == ZigTypeIdPointer && 10470 actual_type->data.pointer.ptr_len == PtrLenSingle && 10471 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 10472 { 10473 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 10474 return ira->codegen->invalid_instruction; 10475 if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 10476 return ira->codegen->invalid_instruction; 10477 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_type) && 10478 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 10479 actual_type->data.pointer.child_type->data.array.child_type, source_node, 10480 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 10481 { 10482 return ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, wanted_type); 10483 } 10484 } 10485 10486 // *[N]T to []T 10487 if (is_slice(wanted_type) && 10488 actual_type->id == ZigTypeIdPointer && 10489 actual_type->data.pointer.ptr_len == PtrLenSingle && 10490 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 10491 { 10492 ZigType *slice_ptr_type = wanted_type->data.structure.fields[slice_ptr_index].type_entry; 10493 assert(slice_ptr_type->id == ZigTypeIdPointer); 10494 ZigType *array_type = actual_type->data.pointer.child_type; 10495 bool const_ok = (slice_ptr_type->data.pointer.is_const || array_type->data.array.len == 0 10496 || !actual_type->data.pointer.is_const); 10497 if (const_ok && types_match_const_cast_only(ira, slice_ptr_type->data.pointer.child_type, 10498 array_type->data.array.child_type, source_node, 10499 !slice_ptr_type->data.pointer.is_const).id == ConstCastResultIdOk) 10500 { 10501 return ir_resolve_ptr_of_array_to_slice(ira, source_instr, value, wanted_type); 10502 } 10503 } 10504 10505 10506 // cast from T to ?T 10507 // note that the *T to ?*T case is handled via the "ConstCastOnly" mechanism 10508 if (wanted_type->id == ZigTypeIdOptional) { 10509 ZigType *wanted_child_type = wanted_type->data.maybe.child_type; 10510 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, 10511 false).id == ConstCastResultIdOk) 10512 { 10513 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); 10514 } else if (actual_type->id == ZigTypeIdComptimeInt || 10515 actual_type->id == ZigTypeIdComptimeFloat) 10516 { 10517 if (ir_num_lit_fits_in_other_type(ira, value, wanted_child_type, true)) { 10518 return ir_analyze_maybe_wrap(ira, source_instr, value, wanted_type); 10519 } else { 10520 return ira->codegen->invalid_instruction; 10521 } 10522 } else if ( 10523 wanted_child_type->id == ZigTypeIdPointer && 10524 wanted_child_type->data.pointer.ptr_len == PtrLenUnknown && 10525 actual_type->id == ZigTypeIdPointer && 10526 actual_type->data.pointer.ptr_len == PtrLenSingle && 10527 actual_type->data.pointer.child_type->id == ZigTypeIdArray) 10528 { 10529 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 10530 return ira->codegen->invalid_instruction; 10531 if ((err = type_resolve(ira->codegen, wanted_child_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 10532 return ira->codegen->invalid_instruction; 10533 if (get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, wanted_child_type) && 10534 types_match_const_cast_only(ira, wanted_child_type->data.pointer.child_type, 10535 actual_type->data.pointer.child_type->data.array.child_type, source_node, 10536 !wanted_child_type->data.pointer.is_const).id == ConstCastResultIdOk) 10537 { 10538 IrInstruction *cast1 = ir_resolve_ptr_of_array_to_unknown_len_ptr(ira, source_instr, value, 10539 wanted_child_type); 10540 if (type_is_invalid(cast1->value.type)) 10541 return ira->codegen->invalid_instruction; 10542 return ir_analyze_maybe_wrap(ira, source_instr, cast1, wanted_type); 10543 } 10544 } 10545 } 10546 10547 // cast from null literal to maybe type 10548 if (wanted_type->id == ZigTypeIdOptional && 10549 actual_type->id == ZigTypeIdNull) 10550 { 10551 return ir_analyze_null_to_maybe(ira, source_instr, value, wanted_type); 10552 } 10553 10554 // cast from child type of error type to error type 10555 if (wanted_type->id == ZigTypeIdErrorUnion) { 10556 if (types_match_const_cast_only(ira, wanted_type->data.error_union.payload_type, actual_type, 10557 source_node, false).id == ConstCastResultIdOk) 10558 { 10559 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); 10560 } else if (actual_type->id == ZigTypeIdComptimeInt || 10561 actual_type->id == ZigTypeIdComptimeFloat) 10562 { 10563 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type->data.error_union.payload_type, true)) { 10564 return ir_analyze_err_wrap_payload(ira, source_instr, value, wanted_type); 10565 } else { 10566 return ira->codegen->invalid_instruction; 10567 } 10568 } 10569 } 10570 10571 // cast from [N]T to E![]const T 10572 if (wanted_type->id == ZigTypeIdErrorUnion && 10573 is_slice(wanted_type->data.error_union.payload_type) && 10574 actual_type->id == ZigTypeIdArray) 10575 { 10576 ZigType *ptr_type = 10577 wanted_type->data.error_union.payload_type->data.structure.fields[slice_ptr_index].type_entry; 10578 assert(ptr_type->id == ZigTypeIdPointer); 10579 if ((ptr_type->data.pointer.is_const || actual_type->data.array.len == 0) && 10580 types_match_const_cast_only(ira, ptr_type->data.pointer.child_type, actual_type->data.array.child_type, 10581 source_node, false).id == ConstCastResultIdOk) 10582 { 10583 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); 10584 if (type_is_invalid(cast1->value.type)) 10585 return ira->codegen->invalid_instruction; 10586 10587 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 10588 if (type_is_invalid(cast2->value.type)) 10589 return ira->codegen->invalid_instruction; 10590 10591 return cast2; 10592 } 10593 } 10594 10595 // cast from error set to error union type 10596 if (wanted_type->id == ZigTypeIdErrorUnion && 10597 actual_type->id == ZigTypeIdErrorSet) 10598 { 10599 return ir_analyze_err_wrap_code(ira, source_instr, value, wanted_type); 10600 } 10601 10602 // cast from T to E!?T 10603 if (wanted_type->id == ZigTypeIdErrorUnion && 10604 wanted_type->data.error_union.payload_type->id == ZigTypeIdOptional && 10605 actual_type->id != ZigTypeIdOptional) 10606 { 10607 ZigType *wanted_child_type = wanted_type->data.error_union.payload_type->data.maybe.child_type; 10608 if (types_match_const_cast_only(ira, wanted_child_type, actual_type, source_node, false).id == ConstCastResultIdOk || 10609 actual_type->id == ZigTypeIdNull || 10610 actual_type->id == ZigTypeIdComptimeInt || 10611 actual_type->id == ZigTypeIdComptimeFloat) 10612 { 10613 IrInstruction *cast1 = ir_analyze_cast(ira, source_instr, wanted_type->data.error_union.payload_type, value); 10614 if (type_is_invalid(cast1->value.type)) 10615 return ira->codegen->invalid_instruction; 10616 10617 IrInstruction *cast2 = ir_analyze_cast(ira, source_instr, wanted_type, cast1); 10618 if (type_is_invalid(cast2->value.type)) 10619 return ira->codegen->invalid_instruction; 10620 10621 return cast2; 10622 } 10623 } 10624 10625 // cast from number literal to another type 10626 if (actual_type->id == ZigTypeIdComptimeFloat || 10627 actual_type->id == ZigTypeIdComptimeInt) 10628 { 10629 if (ir_num_lit_fits_in_other_type(ira, value, wanted_type, true)) { 10630 CastOp op; 10631 if ((actual_type->id == ZigTypeIdComptimeFloat && 10632 wanted_type->id == ZigTypeIdFloat) || 10633 (actual_type->id == ZigTypeIdComptimeInt && 10634 wanted_type->id == ZigTypeIdInt)) 10635 { 10636 op = CastOpNumLitToConcrete; 10637 } else if (wanted_type->id == ZigTypeIdInt) { 10638 op = CastOpFloatToInt; 10639 } else if (wanted_type->id == ZigTypeIdFloat) { 10640 op = CastOpIntToFloat; 10641 } else { 10642 zig_unreachable(); 10643 } 10644 return ir_resolve_cast(ira, source_instr, value, wanted_type, op, false); 10645 } else { 10646 return ira->codegen->invalid_instruction; 10647 } 10648 } 10649 10650 // cast from typed number to integer or float literal. 10651 // works when the number is known at compile time 10652 if (instr_is_comptime(value) && 10653 ((actual_type->id == ZigTypeIdInt && wanted_type->id == ZigTypeIdComptimeInt) || 10654 (actual_type->id == ZigTypeIdFloat && wanted_type->id == ZigTypeIdComptimeFloat))) 10655 { 10656 return ir_analyze_number_to_literal(ira, source_instr, value, wanted_type); 10657 } 10658 10659 // cast from union to the enum type of the union 10660 if (actual_type->id == ZigTypeIdUnion && wanted_type->id == ZigTypeIdEnum) { 10661 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) 10662 return ira->codegen->invalid_instruction; 10663 10664 if (actual_type->data.unionation.tag_type == wanted_type) { 10665 return ir_analyze_union_to_tag(ira, source_instr, value, wanted_type); 10666 } 10667 } 10668 10669 // enum to union which has the enum as the tag type 10670 if (wanted_type->id == ZigTypeIdUnion && actual_type->id == ZigTypeIdEnum && 10671 (wanted_type->data.unionation.decl_node->data.container_decl.auto_enum || 10672 wanted_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr)) 10673 { 10674 if ((err = type_resolve(ira->codegen, wanted_type, ResolveStatusZeroBitsKnown))) 10675 return ira->codegen->invalid_instruction; 10676 10677 if (wanted_type->data.unionation.tag_type == actual_type) { 10678 return ir_analyze_enum_to_union(ira, source_instr, value, wanted_type); 10679 } 10680 } 10681 10682 // cast from *T to *[1]T 10683 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 10684 actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle) 10685 { 10686 ZigType *array_type = wanted_type->data.pointer.child_type; 10687 if (array_type->id == ZigTypeIdArray && array_type->data.array.len == 1 && 10688 types_match_const_cast_only(ira, array_type->data.array.child_type, 10689 actual_type->data.pointer.child_type, source_node, 10690 !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 10691 { 10692 if ((err = type_resolve(ira->codegen, wanted_type->data.pointer.child_type, 10693 ResolveStatusAlignmentKnown))) 10694 { 10695 return ira->codegen->invalid_instruction; 10696 } 10697 if ((err = type_resolve(ira->codegen, actual_type->data.pointer.child_type, 10698 ResolveStatusAlignmentKnown))) 10699 { 10700 return ira->codegen->invalid_instruction; 10701 } 10702 uint32_t wanted_align = get_ptr_align(ira->codegen, wanted_type); 10703 uint32_t actual_align = get_ptr_align(ira->codegen, actual_type); 10704 if (wanted_align > actual_align) { 10705 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 10706 add_error_note(ira->codegen, msg, value->source_node, 10707 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&actual_type->name), actual_align)); 10708 add_error_note(ira->codegen, msg, source_instr->source_node, 10709 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&wanted_type->name), wanted_align)); 10710 return ira->codegen->invalid_instruction; 10711 } 10712 return ir_analyze_ptr_to_array(ira, source_instr, value, wanted_type); 10713 } 10714 } 10715 10716 // cast from *T and [*]T to *c_void and ?*c_void 10717 // but don't do it if the actual type is a double pointer 10718 if (actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.child_type->id != ZigTypeIdPointer) { 10719 ZigType *dest_ptr_type = nullptr; 10720 if (wanted_type->id == ZigTypeIdPointer && 10721 wanted_type->data.pointer.ptr_len == PtrLenSingle && 10722 wanted_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 10723 { 10724 dest_ptr_type = wanted_type; 10725 } else if (wanted_type->id == ZigTypeIdOptional && 10726 wanted_type->data.maybe.child_type->id == ZigTypeIdPointer && 10727 wanted_type->data.maybe.child_type->data.pointer.ptr_len == PtrLenSingle && 10728 wanted_type->data.maybe.child_type->data.pointer.child_type == ira->codegen->builtin_types.entry_c_void) 10729 { 10730 dest_ptr_type = wanted_type->data.maybe.child_type; 10731 } 10732 if (dest_ptr_type != nullptr && 10733 (!actual_type->data.pointer.is_const || dest_ptr_type->data.pointer.is_const) && 10734 (!actual_type->data.pointer.is_volatile || dest_ptr_type->data.pointer.is_volatile) && 10735 actual_type->data.pointer.bit_offset_in_host == dest_ptr_type->data.pointer.bit_offset_in_host && 10736 actual_type->data.pointer.host_int_bytes == dest_ptr_type->data.pointer.host_int_bytes && 10737 get_ptr_align(ira->codegen, actual_type) >= get_ptr_align(ira->codegen, dest_ptr_type)) 10738 { 10739 return ir_analyze_ptr_cast(ira, source_instr, value, wanted_type, source_instr); 10740 } 10741 } 10742 10743 // cast from T to *T where T is zero bits 10744 if (wanted_type->id == ZigTypeIdPointer && wanted_type->data.pointer.ptr_len == PtrLenSingle && 10745 types_match_const_cast_only(ira, wanted_type->data.pointer.child_type, 10746 actual_type, source_node, !wanted_type->data.pointer.is_const).id == ConstCastResultIdOk) 10747 { 10748 if ((err = type_resolve(ira->codegen, actual_type, ResolveStatusZeroBitsKnown))) { 10749 return ira->codegen->invalid_instruction; 10750 } 10751 if (!type_has_bits(actual_type)) { 10752 return ir_get_ref(ira, source_instr, value, false, false); 10753 } 10754 } 10755 10756 10757 // cast from undefined to anything 10758 if (actual_type->id == ZigTypeIdUndefined) { 10759 return ir_analyze_undefined_to_anything(ira, source_instr, value, wanted_type); 10760 } 10761 10762 ErrorMsg *parent_msg = ir_add_error_node(ira, source_instr->source_node, 10763 buf_sprintf("expected type '%s', found '%s'", 10764 buf_ptr(&wanted_type->name), 10765 buf_ptr(&actual_type->name))); 10766 report_recursive_error(ira, source_instr->source_node, &const_cast_result, parent_msg); 10767 return ira->codegen->invalid_instruction; 10768 } 10769 10770 static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, ZigType *expected_type) { 10771 assert(value); 10772 assert(value != ira->codegen->invalid_instruction); 10773 assert(!expected_type || !type_is_invalid(expected_type)); 10774 assert(value->value.type); 10775 assert(!type_is_invalid(value->value.type)); 10776 if (expected_type == nullptr) 10777 return value; // anything will do 10778 if (expected_type == value->value.type) 10779 return value; // match 10780 if (value->value.type->id == ZigTypeIdUnreachable) 10781 return value; 10782 10783 return ir_analyze_cast(ira, value, expected_type, value); 10784 } 10785 10786 static IrInstruction *ir_get_deref(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *ptr) { 10787 Error err; 10788 ZigType *type_entry = ptr->value.type; 10789 if (type_is_invalid(type_entry)) { 10790 return ira->codegen->invalid_instruction; 10791 } else if (type_entry->id == ZigTypeIdPointer) { 10792 ZigType *child_type = type_entry->data.pointer.child_type; 10793 // dereferencing a *u0 is comptime known to be 0 10794 if (child_type->id == ZigTypeIdInt && child_type->data.integral.bit_count == 0) { 10795 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope, 10796 source_instruction->source_node, child_type); 10797 init_const_unsigned_negative(&result->value, child_type, 0, false); 10798 return result; 10799 } 10800 if (instr_is_comptime(ptr)) { 10801 if (ptr->value.special == ConstValSpecialUndef) { 10802 ir_add_error(ira, ptr, buf_sprintf("attempt to dereference undefined value")); 10803 return ira->codegen->invalid_instruction; 10804 } 10805 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst || 10806 ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) 10807 { 10808 ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); 10809 if (pointee->special != ConstValSpecialRuntime) { 10810 IrInstruction *result = ir_create_const(&ira->new_irb, source_instruction->scope, 10811 source_instruction->source_node, child_type); 10812 10813 if ((err = ir_read_const_ptr(ira, source_instruction->source_node, &result->value, 10814 &ptr->value))) 10815 { 10816 return ira->codegen->invalid_instruction; 10817 } 10818 result->value.type = child_type; 10819 return result; 10820 } 10821 } 10822 } 10823 // TODO if the instruction is a const ref instruction we can skip it 10824 IrInstruction *load_ptr_instruction = ir_build_load_ptr(&ira->new_irb, source_instruction->scope, 10825 source_instruction->source_node, ptr); 10826 load_ptr_instruction->value.type = child_type; 10827 return load_ptr_instruction; 10828 } else { 10829 ir_add_error_node(ira, source_instruction->source_node, 10830 buf_sprintf("attempt to dereference non pointer type '%s'", 10831 buf_ptr(&type_entry->name))); 10832 return ira->codegen->invalid_instruction; 10833 } 10834 } 10835 10836 static bool ir_resolve_align(IrAnalyze *ira, IrInstruction *value, uint32_t *out) { 10837 if (type_is_invalid(value->value.type)) 10838 return false; 10839 10840 IrInstruction *casted_value = ir_implicit_cast(ira, value, get_align_amt_type(ira->codegen)); 10841 if (type_is_invalid(casted_value->value.type)) 10842 return false; 10843 10844 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 10845 if (!const_val) 10846 return false; 10847 10848 uint32_t align_bytes = bigint_as_unsigned(&const_val->data.x_bigint); 10849 if (align_bytes == 0) { 10850 ir_add_error(ira, value, buf_sprintf("alignment must be >= 1")); 10851 return false; 10852 } 10853 10854 if (!is_power_of_2(align_bytes)) { 10855 ir_add_error(ira, value, buf_sprintf("alignment value %" PRIu32 " is not a power of 2", align_bytes)); 10856 return false; 10857 } 10858 10859 *out = align_bytes; 10860 return true; 10861 } 10862 10863 static bool ir_resolve_unsigned(IrAnalyze *ira, IrInstruction *value, ZigType *int_type, uint64_t *out) { 10864 if (type_is_invalid(value->value.type)) 10865 return false; 10866 10867 IrInstruction *casted_value = ir_implicit_cast(ira, value, int_type); 10868 if (type_is_invalid(casted_value->value.type)) 10869 return false; 10870 10871 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 10872 if (!const_val) 10873 return false; 10874 10875 *out = bigint_as_unsigned(&const_val->data.x_bigint); 10876 return true; 10877 } 10878 10879 static bool ir_resolve_usize(IrAnalyze *ira, IrInstruction *value, uint64_t *out) { 10880 return ir_resolve_unsigned(ira, value, ira->codegen->builtin_types.entry_usize, out); 10881 } 10882 10883 static bool ir_resolve_bool(IrAnalyze *ira, IrInstruction *value, bool *out) { 10884 if (type_is_invalid(value->value.type)) 10885 return false; 10886 10887 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->codegen->builtin_types.entry_bool); 10888 if (type_is_invalid(casted_value->value.type)) 10889 return false; 10890 10891 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 10892 if (!const_val) 10893 return false; 10894 10895 *out = const_val->data.x_bool; 10896 return true; 10897 } 10898 10899 static bool ir_resolve_comptime(IrAnalyze *ira, IrInstruction *value, bool *out) { 10900 if (!value) { 10901 *out = false; 10902 return true; 10903 } 10904 return ir_resolve_bool(ira, value, out); 10905 } 10906 10907 static bool ir_resolve_atomic_order(IrAnalyze *ira, IrInstruction *value, AtomicOrder *out) { 10908 if (type_is_invalid(value->value.type)) 10909 return false; 10910 10911 ConstExprValue *atomic_order_val = get_builtin_value(ira->codegen, "AtomicOrder"); 10912 assert(atomic_order_val->type->id == ZigTypeIdMetaType); 10913 ZigType *atomic_order_type = atomic_order_val->data.x_type; 10914 10915 IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_order_type); 10916 if (type_is_invalid(casted_value->value.type)) 10917 return false; 10918 10919 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 10920 if (!const_val) 10921 return false; 10922 10923 *out = (AtomicOrder)bigint_as_unsigned(&const_val->data.x_enum_tag); 10924 return true; 10925 } 10926 10927 static bool ir_resolve_atomic_rmw_op(IrAnalyze *ira, IrInstruction *value, AtomicRmwOp *out) { 10928 if (type_is_invalid(value->value.type)) 10929 return false; 10930 10931 ConstExprValue *atomic_rmw_op_val = get_builtin_value(ira->codegen, "AtomicRmwOp"); 10932 assert(atomic_rmw_op_val->type->id == ZigTypeIdMetaType); 10933 ZigType *atomic_rmw_op_type = atomic_rmw_op_val->data.x_type; 10934 10935 IrInstruction *casted_value = ir_implicit_cast(ira, value, atomic_rmw_op_type); 10936 if (type_is_invalid(casted_value->value.type)) 10937 return false; 10938 10939 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 10940 if (!const_val) 10941 return false; 10942 10943 *out = (AtomicRmwOp)bigint_as_unsigned(&const_val->data.x_enum_tag); 10944 return true; 10945 } 10946 10947 static bool ir_resolve_global_linkage(IrAnalyze *ira, IrInstruction *value, GlobalLinkageId *out) { 10948 if (type_is_invalid(value->value.type)) 10949 return false; 10950 10951 ConstExprValue *global_linkage_val = get_builtin_value(ira->codegen, "GlobalLinkage"); 10952 assert(global_linkage_val->type->id == ZigTypeIdMetaType); 10953 ZigType *global_linkage_type = global_linkage_val->data.x_type; 10954 10955 IrInstruction *casted_value = ir_implicit_cast(ira, value, global_linkage_type); 10956 if (type_is_invalid(casted_value->value.type)) 10957 return false; 10958 10959 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 10960 if (!const_val) 10961 return false; 10962 10963 *out = (GlobalLinkageId)bigint_as_unsigned(&const_val->data.x_enum_tag); 10964 return true; 10965 } 10966 10967 static bool ir_resolve_float_mode(IrAnalyze *ira, IrInstruction *value, FloatMode *out) { 10968 if (type_is_invalid(value->value.type)) 10969 return false; 10970 10971 ConstExprValue *float_mode_val = get_builtin_value(ira->codegen, "FloatMode"); 10972 assert(float_mode_val->type->id == ZigTypeIdMetaType); 10973 ZigType *float_mode_type = float_mode_val->data.x_type; 10974 10975 IrInstruction *casted_value = ir_implicit_cast(ira, value, float_mode_type); 10976 if (type_is_invalid(casted_value->value.type)) 10977 return false; 10978 10979 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 10980 if (!const_val) 10981 return false; 10982 10983 *out = (FloatMode)bigint_as_unsigned(&const_val->data.x_enum_tag); 10984 return true; 10985 } 10986 10987 10988 static Buf *ir_resolve_str(IrAnalyze *ira, IrInstruction *value) { 10989 if (type_is_invalid(value->value.type)) 10990 return nullptr; 10991 10992 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 10993 true, false, PtrLenUnknown, 0, 0, 0); 10994 ZigType *str_type = get_slice_type(ira->codegen, ptr_type); 10995 IrInstruction *casted_value = ir_implicit_cast(ira, value, str_type); 10996 if (type_is_invalid(casted_value->value.type)) 10997 return nullptr; 10998 10999 ConstExprValue *const_val = ir_resolve_const(ira, casted_value, UndefBad); 11000 if (!const_val) 11001 return nullptr; 11002 11003 ConstExprValue *ptr_field = &const_val->data.x_struct.fields[slice_ptr_index]; 11004 ConstExprValue *len_field = &const_val->data.x_struct.fields[slice_len_index]; 11005 11006 assert(ptr_field->data.x_ptr.special == ConstPtrSpecialBaseArray); 11007 ConstExprValue *array_val = ptr_field->data.x_ptr.data.base_array.array_val; 11008 if (array_val->data.x_array.special == ConstArraySpecialBuf) { 11009 return array_val->data.x_array.data.s_buf; 11010 } 11011 expand_undef_array(ira->codegen, array_val); 11012 size_t len = bigint_as_unsigned(&len_field->data.x_bigint); 11013 Buf *result = buf_alloc(); 11014 buf_resize(result, len); 11015 for (size_t i = 0; i < len; i += 1) { 11016 size_t new_index = ptr_field->data.x_ptr.data.base_array.elem_index + i; 11017 ConstExprValue *char_val = &array_val->data.x_array.data.s_none.elements[new_index]; 11018 if (char_val->special == ConstValSpecialUndef) { 11019 ir_add_error(ira, casted_value, buf_sprintf("use of undefined value")); 11020 return nullptr; 11021 } 11022 uint64_t big_c = bigint_as_unsigned(&char_val->data.x_bigint); 11023 assert(big_c <= UINT8_MAX); 11024 uint8_t c = (uint8_t)big_c; 11025 buf_ptr(result)[i] = c; 11026 } 11027 return result; 11028 } 11029 11030 static IrInstruction *ir_analyze_instruction_add_implicit_return_type(IrAnalyze *ira, 11031 IrInstructionAddImplicitReturnType *instruction) 11032 { 11033 IrInstruction *value = instruction->value->child; 11034 if (type_is_invalid(value->value.type)) 11035 return ir_unreach_error(ira); 11036 11037 ira->src_implicit_return_type_list.append(value); 11038 11039 return ir_const_void(ira, &instruction->base); 11040 } 11041 11042 static IrInstruction *ir_analyze_instruction_return(IrAnalyze *ira, IrInstructionReturn *instruction) { 11043 IrInstruction *value = instruction->value->child; 11044 if (type_is_invalid(value->value.type)) 11045 return ir_unreach_error(ira); 11046 11047 IrInstruction *casted_value = ir_implicit_cast(ira, value, ira->explicit_return_type); 11048 if (type_is_invalid(casted_value->value.type)) 11049 return ir_unreach_error(ira); 11050 11051 if (casted_value->value.special == ConstValSpecialRuntime && 11052 casted_value->value.type->id == ZigTypeIdPointer && 11053 casted_value->value.data.rh_ptr == RuntimeHintPtrStack) 11054 { 11055 ir_add_error(ira, casted_value, buf_sprintf("function returns address of local variable")); 11056 return ir_unreach_error(ira); 11057 } 11058 IrInstruction *result = ir_build_return(&ira->new_irb, instruction->base.scope, 11059 instruction->base.source_node, casted_value); 11060 result->value.type = ira->codegen->builtin_types.entry_unreachable; 11061 return ir_finish_anal(ira, result); 11062 } 11063 11064 static IrInstruction *ir_analyze_instruction_const(IrAnalyze *ira, IrInstructionConst *instruction) { 11065 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 11066 // TODO determine if we need to use copy_const_val here 11067 result->value = instruction->base.value; 11068 return result; 11069 } 11070 11071 static IrInstruction *ir_analyze_bin_op_bool(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 11072 IrInstruction *op1 = bin_op_instruction->op1->child; 11073 if (type_is_invalid(op1->value.type)) 11074 return ira->codegen->invalid_instruction; 11075 11076 IrInstruction *op2 = bin_op_instruction->op2->child; 11077 if (type_is_invalid(op2->value.type)) 11078 return ira->codegen->invalid_instruction; 11079 11080 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 11081 11082 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, bool_type); 11083 if (casted_op1 == ira->codegen->invalid_instruction) 11084 return ira->codegen->invalid_instruction; 11085 11086 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, bool_type); 11087 if (casted_op2 == ira->codegen->invalid_instruction) 11088 return ira->codegen->invalid_instruction; 11089 11090 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 11091 ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 11092 if (op1_val == nullptr) 11093 return ira->codegen->invalid_instruction; 11094 11095 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 11096 if (op2_val == nullptr) 11097 return ira->codegen->invalid_instruction; 11098 11099 assert(casted_op1->value.type->id == ZigTypeIdBool); 11100 assert(casted_op2->value.type->id == ZigTypeIdBool); 11101 bool result_bool; 11102 if (bin_op_instruction->op_id == IrBinOpBoolOr) { 11103 result_bool = op1_val->data.x_bool || op2_val->data.x_bool; 11104 } else if (bin_op_instruction->op_id == IrBinOpBoolAnd) { 11105 result_bool = op1_val->data.x_bool && op2_val->data.x_bool; 11106 } else { 11107 zig_unreachable(); 11108 } 11109 return ir_const_bool(ira, &bin_op_instruction->base, result_bool); 11110 } 11111 11112 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 11113 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 11114 bin_op_instruction->op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 11115 result->value.type = bool_type; 11116 return result; 11117 } 11118 11119 static bool resolve_cmp_op_id(IrBinOp op_id, Cmp cmp) { 11120 if (op_id == IrBinOpCmpEq) { 11121 return cmp == CmpEQ; 11122 } else if (op_id == IrBinOpCmpNotEq) { 11123 return cmp != CmpEQ; 11124 } else if (op_id == IrBinOpCmpLessThan) { 11125 return cmp == CmpLT; 11126 } else if (op_id == IrBinOpCmpGreaterThan) { 11127 return cmp == CmpGT; 11128 } else if (op_id == IrBinOpCmpLessOrEq) { 11129 return cmp != CmpGT; 11130 } else if (op_id == IrBinOpCmpGreaterOrEq) { 11131 return cmp != CmpLT; 11132 } else { 11133 zig_unreachable(); 11134 } 11135 } 11136 11137 static bool optional_value_is_null(ConstExprValue *val) { 11138 assert(val->special == ConstValSpecialStatic); 11139 if (get_codegen_ptr_type(val->type) != nullptr) { 11140 return val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 11141 val->data.x_ptr.data.hard_coded_addr.addr == 0; 11142 } else { 11143 return val->data.x_optional == nullptr; 11144 } 11145 } 11146 11147 static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 11148 Error err; 11149 IrInstruction *op1 = bin_op_instruction->op1->child; 11150 if (type_is_invalid(op1->value.type)) 11151 return ira->codegen->invalid_instruction; 11152 11153 IrInstruction *op2 = bin_op_instruction->op2->child; 11154 if (type_is_invalid(op2->value.type)) 11155 return ira->codegen->invalid_instruction; 11156 11157 AstNode *source_node = bin_op_instruction->base.source_node; 11158 11159 IrBinOp op_id = bin_op_instruction->op_id; 11160 bool is_equality_cmp = (op_id == IrBinOpCmpEq || op_id == IrBinOpCmpNotEq); 11161 if (is_equality_cmp && 11162 ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdOptional) || 11163 (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdOptional) || 11164 (op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull))) 11165 { 11166 if (op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdNull) { 11167 return ir_const_bool(ira, &bin_op_instruction->base, (op_id == IrBinOpCmpEq)); 11168 } 11169 IrInstruction *maybe_op; 11170 if (op1->value.type->id == ZigTypeIdNull) { 11171 maybe_op = op2; 11172 } else if (op2->value.type->id == ZigTypeIdNull) { 11173 maybe_op = op1; 11174 } else { 11175 zig_unreachable(); 11176 } 11177 if (instr_is_comptime(maybe_op)) { 11178 ConstExprValue *maybe_val = ir_resolve_const(ira, maybe_op, UndefBad); 11179 if (!maybe_val) 11180 return ira->codegen->invalid_instruction; 11181 bool is_null = optional_value_is_null(maybe_val); 11182 bool bool_result = (op_id == IrBinOpCmpEq) ? is_null : !is_null; 11183 return ir_const_bool(ira, &bin_op_instruction->base, bool_result); 11184 } 11185 11186 IrInstruction *is_non_null = ir_build_test_nonnull(&ira->new_irb, bin_op_instruction->base.scope, 11187 source_node, maybe_op); 11188 is_non_null->value.type = ira->codegen->builtin_types.entry_bool; 11189 11190 if (op_id == IrBinOpCmpEq) { 11191 IrInstruction *result = ir_build_bool_not(&ira->new_irb, bin_op_instruction->base.scope, 11192 bin_op_instruction->base.source_node, is_non_null); 11193 result->value.type = ira->codegen->builtin_types.entry_bool; 11194 return result; 11195 } else { 11196 return is_non_null; 11197 } 11198 } else if (op1->value.type->id == ZigTypeIdNull || op2->value.type->id == ZigTypeIdNull) { 11199 ir_add_error_node(ira, source_node, buf_sprintf("comparison against null can only be done with optionals")); 11200 return ira->codegen->invalid_instruction; 11201 } 11202 11203 if (op1->value.type->id == ZigTypeIdErrorSet && op2->value.type->id == ZigTypeIdErrorSet) { 11204 if (!is_equality_cmp) { 11205 ir_add_error_node(ira, source_node, buf_sprintf("operator not allowed for errors")); 11206 return ira->codegen->invalid_instruction; 11207 } 11208 ZigType *intersect_type = get_error_set_intersection(ira, op1->value.type, op2->value.type, source_node); 11209 if (type_is_invalid(intersect_type)) { 11210 return ira->codegen->invalid_instruction; 11211 } 11212 11213 if (!resolve_inferred_error_set(ira->codegen, intersect_type, source_node)) { 11214 return ira->codegen->invalid_instruction; 11215 } 11216 11217 // exception if one of the operators has the type of the empty error set, we allow the comparison 11218 // (and make it comptime known) 11219 // this is a function which is evaluated at comptime and returns an inferred error set will have an empty 11220 // error set. 11221 if (op1->value.type->data.error_set.err_count == 0 || op2->value.type->data.error_set.err_count == 0) { 11222 bool are_equal = false; 11223 bool answer; 11224 if (op_id == IrBinOpCmpEq) { 11225 answer = are_equal; 11226 } else if (op_id == IrBinOpCmpNotEq) { 11227 answer = !are_equal; 11228 } else { 11229 zig_unreachable(); 11230 } 11231 return ir_const_bool(ira, &bin_op_instruction->base, answer); 11232 } 11233 11234 if (!type_is_global_error_set(intersect_type)) { 11235 if (intersect_type->data.error_set.err_count == 0) { 11236 ir_add_error_node(ira, source_node, 11237 buf_sprintf("error sets '%s' and '%s' have no common errors", 11238 buf_ptr(&op1->value.type->name), buf_ptr(&op2->value.type->name))); 11239 return ira->codegen->invalid_instruction; 11240 } 11241 if (op1->value.type->data.error_set.err_count == 1 && op2->value.type->data.error_set.err_count == 1) { 11242 bool are_equal = true; 11243 bool answer; 11244 if (op_id == IrBinOpCmpEq) { 11245 answer = are_equal; 11246 } else if (op_id == IrBinOpCmpNotEq) { 11247 answer = !are_equal; 11248 } else { 11249 zig_unreachable(); 11250 } 11251 return ir_const_bool(ira, &bin_op_instruction->base, answer); 11252 } 11253 } 11254 11255 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 11256 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 11257 if (op1_val == nullptr) 11258 return ira->codegen->invalid_instruction; 11259 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 11260 if (op2_val == nullptr) 11261 return ira->codegen->invalid_instruction; 11262 11263 bool answer; 11264 bool are_equal = op1_val->data.x_err_set->value == op2_val->data.x_err_set->value; 11265 if (op_id == IrBinOpCmpEq) { 11266 answer = are_equal; 11267 } else if (op_id == IrBinOpCmpNotEq) { 11268 answer = !are_equal; 11269 } else { 11270 zig_unreachable(); 11271 } 11272 11273 return ir_const_bool(ira, &bin_op_instruction->base, answer); 11274 } 11275 11276 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 11277 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 11278 op_id, op1, op2, bin_op_instruction->safety_check_on); 11279 result->value.type = ira->codegen->builtin_types.entry_bool; 11280 return result; 11281 } 11282 11283 IrInstruction *instructions[] = {op1, op2}; 11284 ZigType *resolved_type = ir_resolve_peer_types(ira, source_node, nullptr, instructions, 2); 11285 if (type_is_invalid(resolved_type)) 11286 return ira->codegen->invalid_instruction; 11287 11288 bool operator_allowed; 11289 switch (resolved_type->id) { 11290 case ZigTypeIdInvalid: 11291 zig_unreachable(); // handled above 11292 11293 case ZigTypeIdComptimeFloat: 11294 case ZigTypeIdComptimeInt: 11295 case ZigTypeIdInt: 11296 case ZigTypeIdFloat: 11297 operator_allowed = true; 11298 break; 11299 11300 case ZigTypeIdBool: 11301 case ZigTypeIdMetaType: 11302 case ZigTypeIdVoid: 11303 case ZigTypeIdPointer: 11304 case ZigTypeIdErrorSet: 11305 case ZigTypeIdFn: 11306 case ZigTypeIdOpaque: 11307 case ZigTypeIdNamespace: 11308 case ZigTypeIdBoundFn: 11309 case ZigTypeIdArgTuple: 11310 case ZigTypeIdPromise: 11311 case ZigTypeIdEnum: 11312 operator_allowed = is_equality_cmp; 11313 break; 11314 11315 case ZigTypeIdUnreachable: 11316 case ZigTypeIdArray: 11317 case ZigTypeIdStruct: 11318 case ZigTypeIdUndefined: 11319 case ZigTypeIdNull: 11320 case ZigTypeIdErrorUnion: 11321 case ZigTypeIdUnion: 11322 operator_allowed = false; 11323 break; 11324 case ZigTypeIdOptional: 11325 operator_allowed = is_equality_cmp && get_codegen_ptr_type(resolved_type) != nullptr; 11326 break; 11327 } 11328 if (!operator_allowed) { 11329 ir_add_error_node(ira, source_node, 11330 buf_sprintf("operator not allowed for type '%s'", buf_ptr(&resolved_type->name))); 11331 return ira->codegen->invalid_instruction; 11332 } 11333 11334 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 11335 if (casted_op1 == ira->codegen->invalid_instruction) 11336 return ira->codegen->invalid_instruction; 11337 11338 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 11339 if (casted_op2 == ira->codegen->invalid_instruction) 11340 return ira->codegen->invalid_instruction; 11341 11342 if ((err = type_resolve(ira->codegen, resolved_type, ResolveStatusZeroBitsKnown))) 11343 return ira->codegen->invalid_instruction; 11344 11345 bool one_possible_value = !type_requires_comptime(resolved_type) && !type_has_bits(resolved_type); 11346 if (one_possible_value || (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2))) { 11347 ConstExprValue *op1_val = one_possible_value ? &casted_op1->value : ir_resolve_const(ira, casted_op1, UndefBad); 11348 if (op1_val == nullptr) 11349 return ira->codegen->invalid_instruction; 11350 ConstExprValue *op2_val = one_possible_value ? &casted_op2->value : ir_resolve_const(ira, casted_op2, UndefBad); 11351 if (op2_val == nullptr) 11352 return ira->codegen->invalid_instruction; 11353 11354 bool answer; 11355 if (resolved_type->id == ZigTypeIdComptimeFloat || resolved_type->id == ZigTypeIdFloat) { 11356 Cmp cmp_result = float_cmp(op1_val, op2_val); 11357 answer = resolve_cmp_op_id(op_id, cmp_result); 11358 } else if (resolved_type->id == ZigTypeIdComptimeInt || resolved_type->id == ZigTypeIdInt) { 11359 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint); 11360 answer = resolve_cmp_op_id(op_id, cmp_result); 11361 } else { 11362 bool are_equal = one_possible_value || const_values_equal(ira->codegen, op1_val, op2_val); 11363 if (op_id == IrBinOpCmpEq) { 11364 answer = are_equal; 11365 } else if (op_id == IrBinOpCmpNotEq) { 11366 answer = !are_equal; 11367 } else { 11368 zig_unreachable(); 11369 } 11370 } 11371 11372 return ir_const_bool(ira, &bin_op_instruction->base, answer); 11373 } 11374 11375 // some comparisons with unsigned numbers can be evaluated 11376 if (resolved_type->id == ZigTypeIdInt && !resolved_type->data.integral.is_signed) { 11377 ConstExprValue *known_left_val; 11378 IrBinOp flipped_op_id; 11379 if (instr_is_comptime(casted_op1)) { 11380 known_left_val = ir_resolve_const(ira, casted_op1, UndefBad); 11381 if (known_left_val == nullptr) 11382 return ira->codegen->invalid_instruction; 11383 11384 flipped_op_id = op_id; 11385 } else if (instr_is_comptime(casted_op2)) { 11386 known_left_val = ir_resolve_const(ira, casted_op2, UndefBad); 11387 if (known_left_val == nullptr) 11388 return ira->codegen->invalid_instruction; 11389 11390 if (op_id == IrBinOpCmpLessThan) { 11391 flipped_op_id = IrBinOpCmpGreaterThan; 11392 } else if (op_id == IrBinOpCmpGreaterThan) { 11393 flipped_op_id = IrBinOpCmpLessThan; 11394 } else if (op_id == IrBinOpCmpLessOrEq) { 11395 flipped_op_id = IrBinOpCmpGreaterOrEq; 11396 } else if (op_id == IrBinOpCmpGreaterOrEq) { 11397 flipped_op_id = IrBinOpCmpLessOrEq; 11398 } else { 11399 flipped_op_id = op_id; 11400 } 11401 } else { 11402 known_left_val = nullptr; 11403 } 11404 if (known_left_val != nullptr && bigint_cmp_zero(&known_left_val->data.x_bigint) == CmpEQ && 11405 (flipped_op_id == IrBinOpCmpLessOrEq || flipped_op_id == IrBinOpCmpGreaterThan)) 11406 { 11407 bool answer = (flipped_op_id == IrBinOpCmpLessOrEq); 11408 return ir_const_bool(ira, &bin_op_instruction->base, answer); 11409 } 11410 } 11411 11412 IrInstruction *result = ir_build_bin_op(&ira->new_irb, 11413 bin_op_instruction->base.scope, bin_op_instruction->base.source_node, 11414 op_id, casted_op1, casted_op2, bin_op_instruction->safety_check_on); 11415 result->value.type = ira->codegen->builtin_types.entry_bool; 11416 return result; 11417 } 11418 11419 static int ir_eval_math_op(ZigType *type_entry, ConstExprValue *op1_val, 11420 IrBinOp op_id, ConstExprValue *op2_val, ConstExprValue *out_val) 11421 { 11422 bool is_int; 11423 bool is_float; 11424 Cmp op2_zcmp; 11425 if (type_entry->id == ZigTypeIdInt || type_entry->id == ZigTypeIdComptimeInt) { 11426 is_int = true; 11427 is_float = false; 11428 op2_zcmp = bigint_cmp_zero(&op2_val->data.x_bigint); 11429 } else if (type_entry->id == ZigTypeIdFloat || 11430 type_entry->id == ZigTypeIdComptimeFloat) 11431 { 11432 is_int = false; 11433 is_float = true; 11434 op2_zcmp = float_cmp_zero(op2_val); 11435 } else { 11436 zig_unreachable(); 11437 } 11438 11439 if ((op_id == IrBinOpDivUnspecified || op_id == IrBinOpRemRem || op_id == IrBinOpRemMod || 11440 op_id == IrBinOpDivTrunc || op_id == IrBinOpDivFloor) && op2_zcmp == CmpEQ) 11441 { 11442 return ErrorDivByZero; 11443 } 11444 if ((op_id == IrBinOpRemRem || op_id == IrBinOpRemMod) && op2_zcmp == CmpLT) { 11445 return ErrorNegativeDenominator; 11446 } 11447 11448 switch (op_id) { 11449 case IrBinOpInvalid: 11450 case IrBinOpBoolOr: 11451 case IrBinOpBoolAnd: 11452 case IrBinOpCmpEq: 11453 case IrBinOpCmpNotEq: 11454 case IrBinOpCmpLessThan: 11455 case IrBinOpCmpGreaterThan: 11456 case IrBinOpCmpLessOrEq: 11457 case IrBinOpCmpGreaterOrEq: 11458 case IrBinOpArrayCat: 11459 case IrBinOpArrayMult: 11460 case IrBinOpRemUnspecified: 11461 case IrBinOpMergeErrorSets: 11462 zig_unreachable(); 11463 case IrBinOpBinOr: 11464 assert(is_int); 11465 bigint_or(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11466 break; 11467 case IrBinOpBinXor: 11468 assert(is_int); 11469 bigint_xor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11470 break; 11471 case IrBinOpBinAnd: 11472 assert(is_int); 11473 bigint_and(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11474 break; 11475 case IrBinOpBitShiftLeftExact: 11476 assert(is_int); 11477 bigint_shl(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11478 break; 11479 case IrBinOpBitShiftLeftLossy: 11480 assert(type_entry->id == ZigTypeIdInt); 11481 bigint_shl_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 11482 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 11483 break; 11484 case IrBinOpBitShiftRightExact: 11485 { 11486 assert(is_int); 11487 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11488 BigInt orig_bigint; 11489 bigint_shl(&orig_bigint, &out_val->data.x_bigint, &op2_val->data.x_bigint); 11490 if (bigint_cmp(&op1_val->data.x_bigint, &orig_bigint) != CmpEQ) { 11491 return ErrorShiftedOutOneBits; 11492 } 11493 break; 11494 } 11495 case IrBinOpBitShiftRightLossy: 11496 assert(is_int); 11497 bigint_shr(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11498 break; 11499 case IrBinOpAdd: 11500 if (is_int) { 11501 bigint_add(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11502 } else { 11503 float_add(out_val, op1_val, op2_val); 11504 } 11505 break; 11506 case IrBinOpAddWrap: 11507 assert(type_entry->id == ZigTypeIdInt); 11508 bigint_add_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 11509 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 11510 break; 11511 case IrBinOpSub: 11512 if (is_int) { 11513 bigint_sub(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11514 } else { 11515 float_sub(out_val, op1_val, op2_val); 11516 } 11517 break; 11518 case IrBinOpSubWrap: 11519 assert(type_entry->id == ZigTypeIdInt); 11520 bigint_sub_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 11521 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 11522 break; 11523 case IrBinOpMult: 11524 if (is_int) { 11525 bigint_mul(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11526 } else { 11527 float_mul(out_val, op1_val, op2_val); 11528 } 11529 break; 11530 case IrBinOpMultWrap: 11531 assert(type_entry->id == ZigTypeIdInt); 11532 bigint_mul_wrap(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint, 11533 type_entry->data.integral.bit_count, type_entry->data.integral.is_signed); 11534 break; 11535 case IrBinOpDivUnspecified: 11536 assert(is_float); 11537 float_div(out_val, op1_val, op2_val); 11538 break; 11539 case IrBinOpDivTrunc: 11540 if (is_int) { 11541 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11542 } else { 11543 float_div_trunc(out_val, op1_val, op2_val); 11544 } 11545 break; 11546 case IrBinOpDivFloor: 11547 if (is_int) { 11548 bigint_div_floor(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11549 } else { 11550 float_div_floor(out_val, op1_val, op2_val); 11551 } 11552 break; 11553 case IrBinOpDivExact: 11554 if (is_int) { 11555 bigint_div_trunc(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11556 BigInt remainder; 11557 bigint_rem(&remainder, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11558 if (bigint_cmp_zero(&remainder) != CmpEQ) { 11559 return ErrorExactDivRemainder; 11560 } 11561 } else { 11562 float_div_trunc(out_val, op1_val, op2_val); 11563 ConstExprValue remainder; 11564 float_rem(&remainder, op1_val, op2_val); 11565 if (float_cmp_zero(&remainder) != CmpEQ) { 11566 return ErrorExactDivRemainder; 11567 } 11568 } 11569 break; 11570 case IrBinOpRemRem: 11571 if (is_int) { 11572 bigint_rem(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11573 } else { 11574 float_rem(out_val, op1_val, op2_val); 11575 } 11576 break; 11577 case IrBinOpRemMod: 11578 if (is_int) { 11579 bigint_mod(&out_val->data.x_bigint, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11580 } else { 11581 float_mod(out_val, op1_val, op2_val); 11582 } 11583 break; 11584 } 11585 11586 if (type_entry->id == ZigTypeIdInt) { 11587 if (!bigint_fits_in_bits(&out_val->data.x_bigint, type_entry->data.integral.bit_count, 11588 type_entry->data.integral.is_signed)) 11589 { 11590 return ErrorOverflow; 11591 } 11592 } 11593 11594 out_val->type = type_entry; 11595 out_val->special = ConstValSpecialStatic; 11596 return 0; 11597 } 11598 11599 static IrInstruction *ir_analyze_bit_shift(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 11600 IrInstruction *op1 = bin_op_instruction->op1->child; 11601 if (type_is_invalid(op1->value.type)) 11602 return ira->codegen->invalid_instruction; 11603 11604 if (op1->value.type->id != ZigTypeIdInt && op1->value.type->id != ZigTypeIdComptimeInt) { 11605 ir_add_error(ira, &bin_op_instruction->base, 11606 buf_sprintf("bit shifting operation expected integer type, found '%s'", 11607 buf_ptr(&op1->value.type->name))); 11608 return ira->codegen->invalid_instruction; 11609 } 11610 11611 IrInstruction *op2 = bin_op_instruction->op2->child; 11612 if (type_is_invalid(op2->value.type)) 11613 return ira->codegen->invalid_instruction; 11614 11615 IrInstruction *casted_op2; 11616 IrBinOp op_id = bin_op_instruction->op_id; 11617 if (op1->value.type->id == ZigTypeIdComptimeInt) { 11618 casted_op2 = op2; 11619 11620 if (op_id == IrBinOpBitShiftLeftLossy) { 11621 op_id = IrBinOpBitShiftLeftExact; 11622 } 11623 11624 if (casted_op2->value.data.x_bigint.is_negative) { 11625 Buf *val_buf = buf_alloc(); 11626 bigint_append_buf(val_buf, &casted_op2->value.data.x_bigint, 10); 11627 ir_add_error(ira, casted_op2, buf_sprintf("shift by negative value %s", buf_ptr(val_buf))); 11628 return ira->codegen->invalid_instruction; 11629 } 11630 } else { 11631 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 11632 op1->value.type->data.integral.bit_count - 1); 11633 if (bin_op_instruction->op_id == IrBinOpBitShiftLeftLossy && 11634 op2->value.type->id == ZigTypeIdComptimeInt) { 11635 if (!bigint_fits_in_bits(&op2->value.data.x_bigint, 11636 shift_amt_type->data.integral.bit_count, 11637 op2->value.data.x_bigint.is_negative)) { 11638 Buf *val_buf = buf_alloc(); 11639 bigint_append_buf(val_buf, &op2->value.data.x_bigint, 10); 11640 ErrorMsg* msg = ir_add_error(ira, 11641 &bin_op_instruction->base, 11642 buf_sprintf("RHS of shift is too large for LHS type")); 11643 add_error_note( 11644 ira->codegen, 11645 msg, 11646 op2->source_node, 11647 buf_sprintf("value %s cannot fit into type %s", 11648 buf_ptr(val_buf), 11649 buf_ptr(&shift_amt_type->name))); 11650 return ira->codegen->invalid_instruction; 11651 } 11652 } 11653 11654 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 11655 if (casted_op2 == ira->codegen->invalid_instruction) 11656 return ira->codegen->invalid_instruction; 11657 } 11658 11659 if (instr_is_comptime(op1) && instr_is_comptime(casted_op2)) { 11660 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 11661 if (op1_val == nullptr) 11662 return ira->codegen->invalid_instruction; 11663 11664 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 11665 if (op2_val == nullptr) 11666 return ira->codegen->invalid_instruction; 11667 11668 IrInstruction *result_instruction = ir_const(ira, &bin_op_instruction->base, op1->value.type); 11669 11670 int err; 11671 if ((err = ir_eval_math_op(op1->value.type, op1_val, op_id, op2_val, &result_instruction->value))) { 11672 if (err == ErrorOverflow) { 11673 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("operation caused overflow")); 11674 return ira->codegen->invalid_instruction; 11675 } else if (err == ErrorShiftedOutOneBits) { 11676 ir_add_error(ira, &bin_op_instruction->base, buf_sprintf("exact shift shifted out 1 bits")); 11677 return ira->codegen->invalid_instruction; 11678 } else { 11679 zig_unreachable(); 11680 } 11681 return ira->codegen->invalid_instruction; 11682 } 11683 11684 ir_num_lit_fits_in_other_type(ira, result_instruction, op1->value.type, false); 11685 return result_instruction; 11686 } else if (op1->value.type->id == ZigTypeIdComptimeInt) { 11687 ir_add_error(ira, &bin_op_instruction->base, 11688 buf_sprintf("LHS of shift must be an integer type, or RHS must be compile-time known")); 11689 return ira->codegen->invalid_instruction; 11690 } else if (instr_is_comptime(casted_op2) && bigint_cmp_zero(&casted_op2->value.data.x_bigint) == CmpEQ) { 11691 IrInstruction *result = ir_build_cast(&ira->new_irb, bin_op_instruction->base.scope, 11692 bin_op_instruction->base.source_node, op1->value.type, op1, CastOpNoop); 11693 result->value.type = op1->value.type; 11694 return result; 11695 } 11696 11697 IrInstruction *result = ir_build_bin_op(&ira->new_irb, bin_op_instruction->base.scope, 11698 bin_op_instruction->base.source_node, op_id, 11699 op1, casted_op2, bin_op_instruction->safety_check_on); 11700 result->value.type = op1->value.type; 11701 return result; 11702 } 11703 11704 static IrInstruction *ir_analyze_bin_op_math(IrAnalyze *ira, IrInstructionBinOp *instruction) { 11705 IrInstruction *op1 = instruction->op1->child; 11706 if (type_is_invalid(op1->value.type)) 11707 return ira->codegen->invalid_instruction; 11708 11709 IrInstruction *op2 = instruction->op2->child; 11710 if (type_is_invalid(op2->value.type)) 11711 return ira->codegen->invalid_instruction; 11712 11713 IrBinOp op_id = instruction->op_id; 11714 11715 // look for pointer math 11716 if (op1->value.type->id == ZigTypeIdPointer && op1->value.type->data.pointer.ptr_len == PtrLenUnknown && 11717 (op_id == IrBinOpAdd || op_id == IrBinOpSub)) 11718 { 11719 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, ira->codegen->builtin_types.entry_usize); 11720 if (casted_op2 == ira->codegen->invalid_instruction) 11721 return ira->codegen->invalid_instruction; 11722 11723 IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope, 11724 instruction->base.source_node, op_id, op1, casted_op2, true); 11725 result->value.type = op1->value.type; 11726 return result; 11727 } 11728 11729 IrInstruction *instructions[] = {op1, op2}; 11730 ZigType *resolved_type = ir_resolve_peer_types(ira, instruction->base.source_node, nullptr, instructions, 2); 11731 if (type_is_invalid(resolved_type)) 11732 return ira->codegen->invalid_instruction; 11733 11734 bool is_int = resolved_type->id == ZigTypeIdInt || resolved_type->id == ZigTypeIdComptimeInt; 11735 bool is_float = resolved_type->id == ZigTypeIdFloat || resolved_type->id == ZigTypeIdComptimeFloat; 11736 bool is_signed_div = ( 11737 (resolved_type->id == ZigTypeIdInt && resolved_type->data.integral.is_signed) || 11738 resolved_type->id == ZigTypeIdFloat || 11739 (resolved_type->id == ZigTypeIdComptimeFloat && 11740 ((bigfloat_cmp_zero(&op1->value.data.x_bigfloat) != CmpGT) != 11741 (bigfloat_cmp_zero(&op2->value.data.x_bigfloat) != CmpGT))) || 11742 (resolved_type->id == ZigTypeIdComptimeInt && 11743 ((bigint_cmp_zero(&op1->value.data.x_bigint) != CmpGT) != 11744 (bigint_cmp_zero(&op2->value.data.x_bigint) != CmpGT))) 11745 ); 11746 if (op_id == IrBinOpDivUnspecified && is_int) { 11747 if (is_signed_div) { 11748 bool ok = false; 11749 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 11750 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 11751 if (op1_val == nullptr) 11752 return ira->codegen->invalid_instruction; 11753 11754 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 11755 if (op2_val == nullptr) 11756 return ira->codegen->invalid_instruction; 11757 11758 if (bigint_cmp_zero(&op2_val->data.x_bigint) == CmpEQ) { 11759 // the division by zero error will be caught later, but we don't have a 11760 // division function ambiguity problem. 11761 op_id = IrBinOpDivTrunc; 11762 ok = true; 11763 } else { 11764 BigInt trunc_result; 11765 BigInt floor_result; 11766 bigint_div_trunc(&trunc_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11767 bigint_div_floor(&floor_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11768 if (bigint_cmp(&trunc_result, &floor_result) == CmpEQ) { 11769 ok = true; 11770 op_id = IrBinOpDivTrunc; 11771 } 11772 } 11773 } 11774 if (!ok) { 11775 ir_add_error(ira, &instruction->base, 11776 buf_sprintf("division with '%s' and '%s': signed integers must use @divTrunc, @divFloor, or @divExact", 11777 buf_ptr(&op1->value.type->name), 11778 buf_ptr(&op2->value.type->name))); 11779 return ira->codegen->invalid_instruction; 11780 } 11781 } else { 11782 op_id = IrBinOpDivTrunc; 11783 } 11784 } else if (op_id == IrBinOpRemUnspecified) { 11785 if (is_signed_div && (is_int || is_float)) { 11786 bool ok = false; 11787 if (instr_is_comptime(op1) && instr_is_comptime(op2)) { 11788 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 11789 if (op1_val == nullptr) 11790 return ira->codegen->invalid_instruction; 11791 11792 if (is_int) { 11793 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 11794 if (op2_val == nullptr) 11795 return ira->codegen->invalid_instruction; 11796 11797 if (bigint_cmp_zero(&op2->value.data.x_bigint) == CmpEQ) { 11798 // the division by zero error will be caught later, but we don't 11799 // have a remainder function ambiguity problem 11800 ok = true; 11801 } else { 11802 BigInt rem_result; 11803 BigInt mod_result; 11804 bigint_rem(&rem_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11805 bigint_mod(&mod_result, &op1_val->data.x_bigint, &op2_val->data.x_bigint); 11806 ok = bigint_cmp(&rem_result, &mod_result) == CmpEQ; 11807 } 11808 } else { 11809 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 11810 if (casted_op2 == ira->codegen->invalid_instruction) 11811 return ira->codegen->invalid_instruction; 11812 11813 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 11814 if (op2_val == nullptr) 11815 return ira->codegen->invalid_instruction; 11816 11817 if (float_cmp_zero(&casted_op2->value) == CmpEQ) { 11818 // the division by zero error will be caught later, but we don't 11819 // have a remainder function ambiguity problem 11820 ok = true; 11821 } else { 11822 ConstExprValue rem_result; 11823 ConstExprValue mod_result; 11824 float_rem(&rem_result, op1_val, op2_val); 11825 float_mod(&mod_result, op1_val, op2_val); 11826 ok = float_cmp(&rem_result, &mod_result) == CmpEQ; 11827 } 11828 } 11829 } 11830 if (!ok) { 11831 ir_add_error(ira, &instruction->base, 11832 buf_sprintf("remainder division with '%s' and '%s': signed integers and floats must use @rem or @mod", 11833 buf_ptr(&op1->value.type->name), 11834 buf_ptr(&op2->value.type->name))); 11835 return ira->codegen->invalid_instruction; 11836 } 11837 } 11838 op_id = IrBinOpRemRem; 11839 } 11840 11841 if (is_int) { 11842 // int 11843 } else if (is_float && 11844 (op_id == IrBinOpAdd || 11845 op_id == IrBinOpSub || 11846 op_id == IrBinOpMult || 11847 op_id == IrBinOpDivUnspecified || 11848 op_id == IrBinOpDivTrunc || 11849 op_id == IrBinOpDivFloor || 11850 op_id == IrBinOpDivExact || 11851 op_id == IrBinOpRemRem || 11852 op_id == IrBinOpRemMod)) 11853 { 11854 // float 11855 } else { 11856 AstNode *source_node = instruction->base.source_node; 11857 ir_add_error_node(ira, source_node, 11858 buf_sprintf("invalid operands to binary expression: '%s' and '%s'", 11859 buf_ptr(&op1->value.type->name), 11860 buf_ptr(&op2->value.type->name))); 11861 return ira->codegen->invalid_instruction; 11862 } 11863 11864 if (resolved_type->id == ZigTypeIdComptimeInt) { 11865 if (op_id == IrBinOpAddWrap) { 11866 op_id = IrBinOpAdd; 11867 } else if (op_id == IrBinOpSubWrap) { 11868 op_id = IrBinOpSub; 11869 } else if (op_id == IrBinOpMultWrap) { 11870 op_id = IrBinOpMult; 11871 } 11872 } 11873 11874 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, resolved_type); 11875 if (casted_op1 == ira->codegen->invalid_instruction) 11876 return ira->codegen->invalid_instruction; 11877 11878 IrInstruction *casted_op2 = ir_implicit_cast(ira, op2, resolved_type); 11879 if (casted_op2 == ira->codegen->invalid_instruction) 11880 return ira->codegen->invalid_instruction; 11881 11882 if (instr_is_comptime(casted_op1) && instr_is_comptime(casted_op2)) { 11883 ConstExprValue *op1_val = ir_resolve_const(ira, casted_op1, UndefBad); 11884 if (op1_val == nullptr) 11885 return ira->codegen->invalid_instruction; 11886 ConstExprValue *op2_val = ir_resolve_const(ira, casted_op2, UndefBad); 11887 if (op2_val == nullptr) 11888 return ira->codegen->invalid_instruction; 11889 11890 IrInstruction *result_instruction = ir_const(ira, &instruction->base, resolved_type); 11891 11892 int err; 11893 if ((err = ir_eval_math_op(resolved_type, op1_val, op_id, op2_val, &result_instruction->value))) { 11894 if (err == ErrorDivByZero) { 11895 ir_add_error(ira, &instruction->base, buf_sprintf("division by zero")); 11896 return ira->codegen->invalid_instruction; 11897 } else if (err == ErrorOverflow) { 11898 ir_add_error(ira, &instruction->base, buf_sprintf("operation caused overflow")); 11899 return ira->codegen->invalid_instruction; 11900 } else if (err == ErrorExactDivRemainder) { 11901 ir_add_error(ira, &instruction->base, buf_sprintf("exact division had a remainder")); 11902 return ira->codegen->invalid_instruction; 11903 } else if (err == ErrorNegativeDenominator) { 11904 ir_add_error(ira, &instruction->base, buf_sprintf("negative denominator")); 11905 return ira->codegen->invalid_instruction; 11906 } else { 11907 zig_unreachable(); 11908 } 11909 return ira->codegen->invalid_instruction; 11910 } 11911 11912 ir_num_lit_fits_in_other_type(ira, result_instruction, resolved_type, false); 11913 return result_instruction; 11914 } 11915 11916 IrInstruction *result = ir_build_bin_op(&ira->new_irb, instruction->base.scope, 11917 instruction->base.source_node, op_id, casted_op1, casted_op2, instruction->safety_check_on); 11918 result->value.type = resolved_type; 11919 return result; 11920 } 11921 11922 static IrInstruction *ir_analyze_array_cat(IrAnalyze *ira, IrInstructionBinOp *instruction) { 11923 IrInstruction *op1 = instruction->op1->child; 11924 ZigType *op1_type = op1->value.type; 11925 if (type_is_invalid(op1_type)) 11926 return ira->codegen->invalid_instruction; 11927 11928 IrInstruction *op2 = instruction->op2->child; 11929 ZigType *op2_type = op2->value.type; 11930 if (type_is_invalid(op2_type)) 11931 return ira->codegen->invalid_instruction; 11932 11933 ConstExprValue *op1_val = ir_resolve_const(ira, op1, UndefBad); 11934 if (!op1_val) 11935 return ira->codegen->invalid_instruction; 11936 11937 ConstExprValue *op2_val = ir_resolve_const(ira, op2, UndefBad); 11938 if (!op2_val) 11939 return ira->codegen->invalid_instruction; 11940 11941 ConstExprValue *op1_array_val; 11942 size_t op1_array_index; 11943 size_t op1_array_end; 11944 ZigType *child_type; 11945 if (op1_type->id == ZigTypeIdArray) { 11946 child_type = op1_type->data.array.child_type; 11947 op1_array_val = op1_val; 11948 op1_array_index = 0; 11949 op1_array_end = op1_type->data.array.len; 11950 } else if (op1_type->id == ZigTypeIdPointer && 11951 op1_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 11952 op1_val->data.x_ptr.special == ConstPtrSpecialBaseArray && 11953 op1_val->data.x_ptr.data.base_array.is_cstr) 11954 { 11955 child_type = op1_type->data.pointer.child_type; 11956 op1_array_val = op1_val->data.x_ptr.data.base_array.array_val; 11957 op1_array_index = op1_val->data.x_ptr.data.base_array.elem_index; 11958 op1_array_end = op1_array_val->type->data.array.len - 1; 11959 } else if (is_slice(op1_type)) { 11960 ZigType *ptr_type = op1_type->data.structure.fields[slice_ptr_index].type_entry; 11961 child_type = ptr_type->data.pointer.child_type; 11962 ConstExprValue *ptr_val = &op1_val->data.x_struct.fields[slice_ptr_index]; 11963 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 11964 op1_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 11965 op1_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 11966 ConstExprValue *len_val = &op1_val->data.x_struct.fields[slice_len_index]; 11967 op1_array_end = bigint_as_unsigned(&len_val->data.x_bigint); 11968 } else { 11969 ir_add_error(ira, op1, 11970 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op1->value.type->name))); 11971 return ira->codegen->invalid_instruction; 11972 } 11973 11974 ConstExprValue *op2_array_val; 11975 size_t op2_array_index; 11976 size_t op2_array_end; 11977 if (op2_type->id == ZigTypeIdArray) { 11978 if (op2_type->data.array.child_type != child_type) { 11979 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", 11980 buf_ptr(&child_type->name), 11981 buf_ptr(&op2->value.type->name))); 11982 return ira->codegen->invalid_instruction; 11983 } 11984 op2_array_val = op2_val; 11985 op2_array_index = 0; 11986 op2_array_end = op2_array_val->type->data.array.len; 11987 } else if (op2_type->id == ZigTypeIdPointer && 11988 op2_type->data.pointer.child_type == ira->codegen->builtin_types.entry_u8 && 11989 op2_val->data.x_ptr.special == ConstPtrSpecialBaseArray && 11990 op2_val->data.x_ptr.data.base_array.is_cstr) 11991 { 11992 if (child_type != ira->codegen->builtin_types.entry_u8) { 11993 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", 11994 buf_ptr(&child_type->name), 11995 buf_ptr(&op2->value.type->name))); 11996 return ira->codegen->invalid_instruction; 11997 } 11998 op2_array_val = op2_val->data.x_ptr.data.base_array.array_val; 11999 op2_array_index = op2_val->data.x_ptr.data.base_array.elem_index; 12000 op2_array_end = op2_array_val->type->data.array.len - 1; 12001 } else if (is_slice(op2_type)) { 12002 ZigType *ptr_type = op2_type->data.structure.fields[slice_ptr_index].type_entry; 12003 if (ptr_type->data.pointer.child_type != child_type) { 12004 ir_add_error(ira, op2, buf_sprintf("expected array of type '%s', found '%s'", 12005 buf_ptr(&child_type->name), 12006 buf_ptr(&op2->value.type->name))); 12007 return ira->codegen->invalid_instruction; 12008 } 12009 ConstExprValue *ptr_val = &op2_val->data.x_struct.fields[slice_ptr_index]; 12010 assert(ptr_val->data.x_ptr.special == ConstPtrSpecialBaseArray); 12011 op2_array_val = ptr_val->data.x_ptr.data.base_array.array_val; 12012 op2_array_index = ptr_val->data.x_ptr.data.base_array.elem_index; 12013 op2_array_end = op2_array_val->type->data.array.len; 12014 ConstExprValue *len_val = &op2_val->data.x_struct.fields[slice_len_index]; 12015 op2_array_end = bigint_as_unsigned(&len_val->data.x_bigint); 12016 } else { 12017 ir_add_error(ira, op2, 12018 buf_sprintf("expected array or C string literal, found '%s'", buf_ptr(&op2->value.type->name))); 12019 return ira->codegen->invalid_instruction; 12020 } 12021 12022 // The type of result is populated in the following if blocks 12023 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 12024 ConstExprValue *out_val = &result->value; 12025 12026 ConstExprValue *out_array_val; 12027 size_t new_len = (op1_array_end - op1_array_index) + (op2_array_end - op2_array_index); 12028 if (op1_type->id == ZigTypeIdArray || op2_type->id == ZigTypeIdArray) { 12029 result->value.type = get_array_type(ira->codegen, child_type, new_len); 12030 12031 out_array_val = out_val; 12032 } else if (is_slice(op1_type) || is_slice(op2_type)) { 12033 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, 12034 true, false, PtrLenUnknown, 0, 0, 0); 12035 result->value.type = get_slice_type(ira->codegen, ptr_type); 12036 out_array_val = create_const_vals(1); 12037 out_array_val->special = ConstValSpecialStatic; 12038 out_array_val->type = get_array_type(ira->codegen, child_type, new_len); 12039 12040 out_val->data.x_struct.fields = create_const_vals(2); 12041 12042 out_val->data.x_struct.fields[slice_ptr_index].type = ptr_type; 12043 out_val->data.x_struct.fields[slice_ptr_index].special = ConstValSpecialStatic; 12044 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.special = ConstPtrSpecialBaseArray; 12045 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.array_val = out_array_val; 12046 out_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.data.base_array.elem_index = 0; 12047 12048 out_val->data.x_struct.fields[slice_len_index].type = ira->codegen->builtin_types.entry_usize; 12049 out_val->data.x_struct.fields[slice_len_index].special = ConstValSpecialStatic; 12050 bigint_init_unsigned(&out_val->data.x_struct.fields[slice_len_index].data.x_bigint, new_len); 12051 } else { 12052 new_len += 1; // null byte 12053 12054 // TODO make this `[*]null T` instead of `[*]T` 12055 result->value.type = get_pointer_to_type_extra(ira->codegen, child_type, true, false, PtrLenUnknown, 0, 0, 0); 12056 12057 out_array_val = create_const_vals(1); 12058 out_array_val->special = ConstValSpecialStatic; 12059 out_array_val->type = get_array_type(ira->codegen, child_type, new_len); 12060 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 12061 out_val->data.x_ptr.data.base_array.is_cstr = true; 12062 out_val->data.x_ptr.data.base_array.array_val = out_array_val; 12063 out_val->data.x_ptr.data.base_array.elem_index = 0; 12064 } 12065 12066 if (op1_array_val->data.x_array.special == ConstArraySpecialUndef && 12067 op2_array_val->data.x_array.special == ConstArraySpecialUndef) { 12068 out_array_val->data.x_array.special = ConstArraySpecialUndef; 12069 return result; 12070 } 12071 12072 out_array_val->data.x_array.data.s_none.elements = create_const_vals(new_len); 12073 // TODO handle the buf case here for an optimization 12074 expand_undef_array(ira->codegen, op1_array_val); 12075 expand_undef_array(ira->codegen, op2_array_val); 12076 12077 size_t next_index = 0; 12078 for (size_t i = op1_array_index; i < op1_array_end; i += 1, next_index += 1) { 12079 out_array_val->data.x_array.data.s_none.elements[next_index] = op1_array_val->data.x_array.data.s_none.elements[i]; 12080 } 12081 for (size_t i = op2_array_index; i < op2_array_end; i += 1, next_index += 1) { 12082 out_array_val->data.x_array.data.s_none.elements[next_index] = op2_array_val->data.x_array.data.s_none.elements[i]; 12083 } 12084 if (next_index < new_len) { 12085 ConstExprValue *null_byte = &out_array_val->data.x_array.data.s_none.elements[next_index]; 12086 init_const_unsigned_negative(null_byte, child_type, 0, false); 12087 next_index += 1; 12088 } 12089 assert(next_index == new_len); 12090 12091 return result; 12092 } 12093 12094 static IrInstruction *ir_analyze_array_mult(IrAnalyze *ira, IrInstructionBinOp *instruction) { 12095 IrInstruction *op1 = instruction->op1->child; 12096 if (type_is_invalid(op1->value.type)) 12097 return ira->codegen->invalid_instruction; 12098 12099 IrInstruction *op2 = instruction->op2->child; 12100 if (type_is_invalid(op2->value.type)) 12101 return ira->codegen->invalid_instruction; 12102 12103 ConstExprValue *array_val = ir_resolve_const(ira, op1, UndefBad); 12104 if (!array_val) 12105 return ira->codegen->invalid_instruction; 12106 12107 uint64_t mult_amt; 12108 if (!ir_resolve_usize(ira, op2, &mult_amt)) 12109 return ira->codegen->invalid_instruction; 12110 12111 ZigType *array_type = op1->value.type; 12112 if (array_type->id != ZigTypeIdArray) { 12113 ir_add_error(ira, op1, buf_sprintf("expected array type, found '%s'", buf_ptr(&op1->value.type->name))); 12114 return ira->codegen->invalid_instruction; 12115 } 12116 12117 uint64_t old_array_len = array_type->data.array.len; 12118 uint64_t new_array_len; 12119 12120 if (mul_u64_overflow(old_array_len, mult_amt, &new_array_len)) 12121 { 12122 ir_add_error(ira, &instruction->base, buf_sprintf("operation results in overflow")); 12123 return ira->codegen->invalid_instruction; 12124 } 12125 12126 ZigType *child_type = array_type->data.array.child_type; 12127 12128 IrInstruction *result = ir_const(ira, &instruction->base, 12129 get_array_type(ira->codegen, child_type, new_array_len)); 12130 ConstExprValue *out_val = &result->value; 12131 if (array_val->data.x_array.special == ConstArraySpecialUndef) { 12132 out_val->data.x_array.special = ConstArraySpecialUndef; 12133 return result; 12134 } 12135 12136 // TODO optimize the buf case 12137 expand_undef_array(ira->codegen, array_val); 12138 out_val->data.x_array.data.s_none.elements = create_const_vals(new_array_len); 12139 12140 uint64_t i = 0; 12141 for (uint64_t x = 0; x < mult_amt; x += 1) { 12142 for (uint64_t y = 0; y < old_array_len; y += 1) { 12143 out_val->data.x_array.data.s_none.elements[i] = array_val->data.x_array.data.s_none.elements[y]; 12144 i += 1; 12145 } 12146 } 12147 assert(i == new_array_len); 12148 12149 return result; 12150 } 12151 12152 static IrInstruction *ir_analyze_merge_error_sets(IrAnalyze *ira, IrInstructionBinOp *instruction) { 12153 ZigType *op1_type = ir_resolve_type(ira, instruction->op1->child); 12154 if (type_is_invalid(op1_type)) 12155 return ira->codegen->invalid_instruction; 12156 12157 if (op1_type->id != ZigTypeIdErrorSet) { 12158 ir_add_error(ira, instruction->op1, 12159 buf_sprintf("expected error set type, found '%s'", buf_ptr(&op1_type->name))); 12160 return ira->codegen->invalid_instruction; 12161 } 12162 12163 ZigType *op2_type = ir_resolve_type(ira, instruction->op2->child); 12164 if (type_is_invalid(op2_type)) 12165 return ira->codegen->invalid_instruction; 12166 12167 if (op2_type->id != ZigTypeIdErrorSet) { 12168 ir_add_error(ira, instruction->op2, 12169 buf_sprintf("expected error set type, found '%s'", buf_ptr(&op2_type->name))); 12170 return ira->codegen->invalid_instruction; 12171 } 12172 12173 if (type_is_global_error_set(op1_type) || 12174 type_is_global_error_set(op2_type)) 12175 { 12176 return ir_const_type(ira, &instruction->base, ira->codegen->builtin_types.entry_global_error_set); 12177 } 12178 12179 if (!resolve_inferred_error_set(ira->codegen, op1_type, instruction->op1->child->source_node)) { 12180 return ira->codegen->invalid_instruction; 12181 } 12182 12183 if (!resolve_inferred_error_set(ira->codegen, op2_type, instruction->op2->child->source_node)) { 12184 return ira->codegen->invalid_instruction; 12185 } 12186 12187 ErrorTableEntry **errors = allocate<ErrorTableEntry *>(ira->codegen->errors_by_index.length); 12188 for (uint32_t i = 0, count = op1_type->data.error_set.err_count; i < count; i += 1) { 12189 ErrorTableEntry *error_entry = op1_type->data.error_set.errors[i]; 12190 assert(errors[error_entry->value] == nullptr); 12191 errors[error_entry->value] = error_entry; 12192 } 12193 ZigType *result_type = get_error_set_union(ira->codegen, errors, op1_type, op2_type); 12194 free(errors); 12195 12196 return ir_const_type(ira, &instruction->base, result_type); 12197 } 12198 12199 static IrInstruction *ir_analyze_instruction_bin_op(IrAnalyze *ira, IrInstructionBinOp *bin_op_instruction) { 12200 IrBinOp op_id = bin_op_instruction->op_id; 12201 switch (op_id) { 12202 case IrBinOpInvalid: 12203 zig_unreachable(); 12204 case IrBinOpBoolOr: 12205 case IrBinOpBoolAnd: 12206 return ir_analyze_bin_op_bool(ira, bin_op_instruction); 12207 case IrBinOpCmpEq: 12208 case IrBinOpCmpNotEq: 12209 case IrBinOpCmpLessThan: 12210 case IrBinOpCmpGreaterThan: 12211 case IrBinOpCmpLessOrEq: 12212 case IrBinOpCmpGreaterOrEq: 12213 return ir_analyze_bin_op_cmp(ira, bin_op_instruction); 12214 case IrBinOpBitShiftLeftLossy: 12215 case IrBinOpBitShiftLeftExact: 12216 case IrBinOpBitShiftRightLossy: 12217 case IrBinOpBitShiftRightExact: 12218 return ir_analyze_bit_shift(ira, bin_op_instruction); 12219 case IrBinOpBinOr: 12220 case IrBinOpBinXor: 12221 case IrBinOpBinAnd: 12222 case IrBinOpAdd: 12223 case IrBinOpAddWrap: 12224 case IrBinOpSub: 12225 case IrBinOpSubWrap: 12226 case IrBinOpMult: 12227 case IrBinOpMultWrap: 12228 case IrBinOpDivUnspecified: 12229 case IrBinOpDivTrunc: 12230 case IrBinOpDivFloor: 12231 case IrBinOpDivExact: 12232 case IrBinOpRemUnspecified: 12233 case IrBinOpRemRem: 12234 case IrBinOpRemMod: 12235 return ir_analyze_bin_op_math(ira, bin_op_instruction); 12236 case IrBinOpArrayCat: 12237 return ir_analyze_array_cat(ira, bin_op_instruction); 12238 case IrBinOpArrayMult: 12239 return ir_analyze_array_mult(ira, bin_op_instruction); 12240 case IrBinOpMergeErrorSets: 12241 return ir_analyze_merge_error_sets(ira, bin_op_instruction); 12242 } 12243 zig_unreachable(); 12244 } 12245 12246 static IrInstruction *ir_analyze_instruction_decl_var(IrAnalyze *ira, IrInstructionDeclVar *decl_var_instruction) { 12247 Error err; 12248 ZigVar *var = decl_var_instruction->var; 12249 12250 IrInstruction *init_value = decl_var_instruction->init_value->child; 12251 if (type_is_invalid(init_value->value.type)) { 12252 var->value->type = ira->codegen->builtin_types.entry_invalid; 12253 return ira->codegen->invalid_instruction; 12254 } 12255 12256 ZigType *explicit_type = nullptr; 12257 IrInstruction *var_type = nullptr; 12258 if (decl_var_instruction->var_type != nullptr) { 12259 var_type = decl_var_instruction->var_type->child; 12260 ZigType *proposed_type = ir_resolve_type(ira, var_type); 12261 explicit_type = validate_var_type(ira->codegen, var_type->source_node, proposed_type); 12262 if (type_is_invalid(explicit_type)) { 12263 var->value->type = ira->codegen->builtin_types.entry_invalid; 12264 return ira->codegen->invalid_instruction; 12265 } 12266 } 12267 12268 AstNode *source_node = decl_var_instruction->base.source_node; 12269 12270 IrInstruction *casted_init_value = ir_implicit_cast(ira, init_value, explicit_type); 12271 bool is_comptime_var = ir_get_var_is_comptime(var); 12272 12273 bool var_class_requires_const = false; 12274 12275 ZigType *result_type = casted_init_value->value.type; 12276 if (type_is_invalid(result_type)) { 12277 result_type = ira->codegen->builtin_types.entry_invalid; 12278 } else { 12279 if ((err = type_resolve(ira->codegen, result_type, ResolveStatusZeroBitsKnown))) { 12280 result_type = ira->codegen->builtin_types.entry_invalid; 12281 } 12282 } 12283 12284 if (!type_is_invalid(result_type)) { 12285 if (result_type->id == ZigTypeIdUnreachable || 12286 result_type->id == ZigTypeIdOpaque) 12287 { 12288 ir_add_error_node(ira, source_node, 12289 buf_sprintf("variable of type '%s' not allowed", buf_ptr(&result_type->name))); 12290 result_type = ira->codegen->builtin_types.entry_invalid; 12291 } else if (type_requires_comptime(result_type)) { 12292 var_class_requires_const = true; 12293 if (!var->gen_is_const && !is_comptime_var) { 12294 ir_add_error_node(ira, source_node, 12295 buf_sprintf("variable of type '%s' must be const or comptime", 12296 buf_ptr(&result_type->name))); 12297 result_type = ira->codegen->builtin_types.entry_invalid; 12298 } 12299 } else { 12300 if (casted_init_value->value.special == ConstValSpecialStatic && 12301 casted_init_value->value.type->id == ZigTypeIdFn && 12302 casted_init_value->value.data.x_ptr.data.fn.fn_entry->fn_inline == FnInlineAlways) 12303 { 12304 var_class_requires_const = true; 12305 if (!var->src_is_const && !is_comptime_var) { 12306 ErrorMsg *msg = ir_add_error_node(ira, source_node, 12307 buf_sprintf("functions marked inline must be stored in const or comptime var")); 12308 AstNode *proto_node = casted_init_value->value.data.x_ptr.data.fn.fn_entry->proto_node; 12309 add_error_note(ira->codegen, msg, proto_node, buf_sprintf("declared here")); 12310 result_type = ira->codegen->builtin_types.entry_invalid; 12311 } 12312 } 12313 } 12314 } 12315 12316 if (var->value->type != nullptr && !is_comptime_var) { 12317 // This is at least the second time we've seen this variable declaration during analysis. 12318 // This means that this is actually a different variable due to, e.g. an inline while loop. 12319 // We make a new variable so that it can hold a different type, and so the debug info can 12320 // be distinct. 12321 ZigVar *new_var = create_local_var(ira->codegen, var->decl_node, var->child_scope, 12322 &var->name, var->src_is_const, var->gen_is_const, var->shadowable, var->is_comptime, true); 12323 new_var->owner_exec = var->owner_exec; 12324 new_var->align_bytes = var->align_bytes; 12325 if (var->mem_slot_index != SIZE_MAX) { 12326 ConstExprValue *vals = create_const_vals(1); 12327 new_var->mem_slot_index = ira->exec_context.mem_slot_list.length; 12328 ira->exec_context.mem_slot_list.append(vals); 12329 } 12330 12331 var->next_var = new_var; 12332 var = new_var; 12333 } 12334 12335 // This must be done after possibly creating a new variable above 12336 var->ref_count = 0; 12337 12338 var->value->type = result_type; 12339 assert(var->value->type); 12340 12341 if (type_is_invalid(result_type)) { 12342 return ir_const_void(ira, &decl_var_instruction->base); 12343 } 12344 12345 if (decl_var_instruction->align_value == nullptr) { 12346 if ((err = type_resolve(ira->codegen, result_type, ResolveStatusAlignmentKnown))) { 12347 var->value->type = ira->codegen->builtin_types.entry_invalid; 12348 return ir_const_void(ira, &decl_var_instruction->base); 12349 } 12350 var->align_bytes = get_abi_alignment(ira->codegen, result_type); 12351 } else { 12352 if (!ir_resolve_align(ira, decl_var_instruction->align_value->child, &var->align_bytes)) { 12353 var->value->type = ira->codegen->builtin_types.entry_invalid; 12354 } 12355 } 12356 12357 if (casted_init_value->value.special != ConstValSpecialRuntime) { 12358 if (var->mem_slot_index != SIZE_MAX) { 12359 assert(var->mem_slot_index < ira->exec_context.mem_slot_list.length); 12360 ConstExprValue *mem_slot = ira->exec_context.mem_slot_list.at(var->mem_slot_index); 12361 copy_const_val(mem_slot, &casted_init_value->value, !is_comptime_var || var->gen_is_const); 12362 12363 if (is_comptime_var || (var_class_requires_const && var->gen_is_const)) { 12364 return ir_const_void(ira, &decl_var_instruction->base); 12365 } 12366 } 12367 } else if (is_comptime_var) { 12368 ir_add_error(ira, &decl_var_instruction->base, 12369 buf_sprintf("cannot store runtime value in compile time variable")); 12370 var->value->type = ira->codegen->builtin_types.entry_invalid; 12371 return ira->codegen->invalid_instruction; 12372 } 12373 12374 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 12375 if (fn_entry) 12376 fn_entry->variable_list.append(var); 12377 12378 IrInstruction *result = ir_build_var_decl(&ira->new_irb, 12379 decl_var_instruction->base.scope, decl_var_instruction->base.source_node, 12380 var, var_type, nullptr, casted_init_value); 12381 result->value.type = ira->codegen->builtin_types.entry_void; 12382 return result; 12383 } 12384 12385 static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructionExport *instruction) { 12386 IrInstruction *name = instruction->name->child; 12387 Buf *symbol_name = ir_resolve_str(ira, name); 12388 if (symbol_name == nullptr) { 12389 return ira->codegen->invalid_instruction; 12390 } 12391 12392 IrInstruction *target = instruction->target->child; 12393 if (type_is_invalid(target->value.type)) { 12394 return ira->codegen->invalid_instruction; 12395 } 12396 12397 GlobalLinkageId global_linkage_id = GlobalLinkageIdStrong; 12398 if (instruction->linkage != nullptr) { 12399 IrInstruction *linkage_value = instruction->linkage->child; 12400 if (!ir_resolve_global_linkage(ira, linkage_value, &global_linkage_id)) { 12401 return ira->codegen->invalid_instruction; 12402 } 12403 } 12404 12405 auto entry = ira->codegen->exported_symbol_names.put_unique(symbol_name, instruction->base.source_node); 12406 if (entry) { 12407 AstNode *other_export_node = entry->value; 12408 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 12409 buf_sprintf("exported symbol collision: '%s'", buf_ptr(symbol_name))); 12410 add_error_note(ira->codegen, msg, other_export_node, buf_sprintf("other symbol is here")); 12411 } 12412 12413 switch (target->value.type->id) { 12414 case ZigTypeIdInvalid: 12415 case ZigTypeIdUnreachable: 12416 zig_unreachable(); 12417 case ZigTypeIdFn: { 12418 assert(target->value.data.x_ptr.special == ConstPtrSpecialFunction); 12419 ZigFn *fn_entry = target->value.data.x_ptr.data.fn.fn_entry; 12420 CallingConvention cc = fn_entry->type_entry->data.fn.fn_type_id.cc; 12421 switch (cc) { 12422 case CallingConventionUnspecified: { 12423 ErrorMsg *msg = ir_add_error(ira, target, 12424 buf_sprintf("exported function must specify calling convention")); 12425 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 12426 } break; 12427 case CallingConventionAsync: { 12428 ErrorMsg *msg = ir_add_error(ira, target, 12429 buf_sprintf("exported function cannot be async")); 12430 add_error_note(ira->codegen, msg, fn_entry->proto_node, buf_sprintf("declared here")); 12431 } break; 12432 case CallingConventionC: 12433 case CallingConventionNaked: 12434 case CallingConventionCold: 12435 case CallingConventionStdcall: 12436 add_fn_export(ira->codegen, fn_entry, symbol_name, global_linkage_id, cc == CallingConventionC); 12437 break; 12438 } 12439 } break; 12440 case ZigTypeIdStruct: 12441 if (is_slice(target->value.type)) { 12442 ir_add_error(ira, target, 12443 buf_sprintf("unable to export value of type '%s'", buf_ptr(&target->value.type->name))); 12444 } else if (target->value.type->data.structure.layout != ContainerLayoutExtern) { 12445 ErrorMsg *msg = ir_add_error(ira, target, 12446 buf_sprintf("exported struct value must be declared extern")); 12447 add_error_note(ira->codegen, msg, target->value.type->data.structure.decl_node, buf_sprintf("declared here")); 12448 } 12449 break; 12450 case ZigTypeIdUnion: 12451 if (target->value.type->data.unionation.layout != ContainerLayoutExtern) { 12452 ErrorMsg *msg = ir_add_error(ira, target, 12453 buf_sprintf("exported union value must be declared extern")); 12454 add_error_note(ira->codegen, msg, target->value.type->data.unionation.decl_node, buf_sprintf("declared here")); 12455 } 12456 break; 12457 case ZigTypeIdEnum: 12458 if (target->value.type->data.enumeration.layout != ContainerLayoutExtern) { 12459 ErrorMsg *msg = ir_add_error(ira, target, 12460 buf_sprintf("exported enum value must be declared extern")); 12461 add_error_note(ira->codegen, msg, target->value.type->data.enumeration.decl_node, buf_sprintf("declared here")); 12462 } 12463 break; 12464 case ZigTypeIdMetaType: { 12465 ZigType *type_value = target->value.data.x_type; 12466 switch (type_value->id) { 12467 case ZigTypeIdInvalid: 12468 zig_unreachable(); 12469 case ZigTypeIdStruct: 12470 if (is_slice(type_value)) { 12471 ir_add_error(ira, target, 12472 buf_sprintf("unable to export type '%s'", buf_ptr(&type_value->name))); 12473 } else if (type_value->data.structure.layout != ContainerLayoutExtern) { 12474 ErrorMsg *msg = ir_add_error(ira, target, 12475 buf_sprintf("exported struct must be declared extern")); 12476 add_error_note(ira->codegen, msg, type_value->data.structure.decl_node, buf_sprintf("declared here")); 12477 } 12478 break; 12479 case ZigTypeIdUnion: 12480 if (type_value->data.unionation.layout != ContainerLayoutExtern) { 12481 ErrorMsg *msg = ir_add_error(ira, target, 12482 buf_sprintf("exported union must be declared extern")); 12483 add_error_note(ira->codegen, msg, type_value->data.unionation.decl_node, buf_sprintf("declared here")); 12484 } 12485 break; 12486 case ZigTypeIdEnum: 12487 if (type_value->data.enumeration.layout != ContainerLayoutExtern) { 12488 ErrorMsg *msg = ir_add_error(ira, target, 12489 buf_sprintf("exported enum must be declared extern")); 12490 add_error_note(ira->codegen, msg, type_value->data.enumeration.decl_node, buf_sprintf("declared here")); 12491 } 12492 break; 12493 case ZigTypeIdFn: { 12494 if (type_value->data.fn.fn_type_id.cc == CallingConventionUnspecified) { 12495 ir_add_error(ira, target, 12496 buf_sprintf("exported function type must specify calling convention")); 12497 } 12498 } break; 12499 case ZigTypeIdInt: 12500 case ZigTypeIdFloat: 12501 case ZigTypeIdPointer: 12502 case ZigTypeIdArray: 12503 case ZigTypeIdBool: 12504 break; 12505 case ZigTypeIdMetaType: 12506 case ZigTypeIdVoid: 12507 case ZigTypeIdUnreachable: 12508 case ZigTypeIdComptimeFloat: 12509 case ZigTypeIdComptimeInt: 12510 case ZigTypeIdUndefined: 12511 case ZigTypeIdNull: 12512 case ZigTypeIdOptional: 12513 case ZigTypeIdErrorUnion: 12514 case ZigTypeIdErrorSet: 12515 case ZigTypeIdNamespace: 12516 case ZigTypeIdBoundFn: 12517 case ZigTypeIdArgTuple: 12518 case ZigTypeIdOpaque: 12519 case ZigTypeIdPromise: 12520 ir_add_error(ira, target, 12521 buf_sprintf("invalid export target '%s'", buf_ptr(&type_value->name))); 12522 break; 12523 } 12524 } break; 12525 case ZigTypeIdVoid: 12526 case ZigTypeIdBool: 12527 case ZigTypeIdInt: 12528 case ZigTypeIdFloat: 12529 case ZigTypeIdPointer: 12530 case ZigTypeIdArray: 12531 case ZigTypeIdComptimeFloat: 12532 case ZigTypeIdComptimeInt: 12533 case ZigTypeIdUndefined: 12534 case ZigTypeIdNull: 12535 case ZigTypeIdOptional: 12536 case ZigTypeIdErrorUnion: 12537 case ZigTypeIdErrorSet: 12538 zig_panic("TODO export const value of type %s", buf_ptr(&target->value.type->name)); 12539 case ZigTypeIdNamespace: 12540 case ZigTypeIdBoundFn: 12541 case ZigTypeIdArgTuple: 12542 case ZigTypeIdOpaque: 12543 case ZigTypeIdPromise: 12544 ir_add_error(ira, target, 12545 buf_sprintf("invalid export target type '%s'", buf_ptr(&target->value.type->name))); 12546 break; 12547 } 12548 12549 return ir_const_void(ira, &instruction->base); 12550 } 12551 12552 static bool exec_has_err_ret_trace(CodeGen *g, IrExecutable *exec) { 12553 ZigFn *fn_entry = exec_fn_entry(exec); 12554 return fn_entry != nullptr && fn_entry->calls_or_awaits_errorable_fn && g->have_err_ret_tracing; 12555 } 12556 12557 static IrInstruction *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, 12558 IrInstructionErrorReturnTrace *instruction) 12559 { 12560 if (instruction->optional == IrInstructionErrorReturnTrace::Null) { 12561 ZigType *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(ira->codegen); 12562 ZigType *optional_type = get_optional_type(ira->codegen, ptr_to_stack_trace_type); 12563 if (!exec_has_err_ret_trace(ira->codegen, ira->new_irb.exec)) { 12564 IrInstruction *result = ir_const(ira, &instruction->base, optional_type); 12565 ConstExprValue *out_val = &result->value; 12566 assert(get_codegen_ptr_type(optional_type) != nullptr); 12567 out_val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 12568 out_val->data.x_ptr.data.hard_coded_addr.addr = 0; 12569 return result; 12570 } 12571 IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, 12572 instruction->base.source_node, instruction->optional); 12573 new_instruction->value.type = optional_type; 12574 return new_instruction; 12575 } else { 12576 assert(ira->codegen->have_err_ret_tracing); 12577 IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, 12578 instruction->base.source_node, instruction->optional); 12579 new_instruction->value.type = get_ptr_to_stack_trace_type(ira->codegen); 12580 return new_instruction; 12581 } 12582 } 12583 12584 static IrInstruction *ir_analyze_instruction_error_union(IrAnalyze *ira, 12585 IrInstructionErrorUnion *instruction) 12586 { 12587 Error err; 12588 12589 ZigType *err_set_type = ir_resolve_type(ira, instruction->err_set->child); 12590 if (type_is_invalid(err_set_type)) 12591 return ira->codegen->invalid_instruction; 12592 12593 ZigType *payload_type = ir_resolve_type(ira, instruction->payload->child); 12594 if (type_is_invalid(payload_type)) 12595 return ira->codegen->invalid_instruction; 12596 12597 if (err_set_type->id != ZigTypeIdErrorSet) { 12598 ir_add_error(ira, instruction->err_set->child, 12599 buf_sprintf("expected error set type, found type '%s'", 12600 buf_ptr(&err_set_type->name))); 12601 return ira->codegen->invalid_instruction; 12602 } 12603 12604 if ((err = type_resolve(ira->codegen, payload_type, ResolveStatusSizeKnown))) 12605 return ira->codegen->invalid_instruction; 12606 ZigType *result_type = get_error_union_type(ira->codegen, err_set_type, payload_type); 12607 12608 return ir_const_type(ira, &instruction->base, result_type); 12609 } 12610 12611 IrInstruction *ir_get_implicit_allocator(IrAnalyze *ira, IrInstruction *source_instr, ImplicitAllocatorId id) { 12612 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 12613 if (parent_fn_entry == nullptr) { 12614 ir_add_error(ira, source_instr, buf_sprintf("no implicit allocator available")); 12615 return ira->codegen->invalid_instruction; 12616 } 12617 12618 FnTypeId *parent_fn_type = &parent_fn_entry->type_entry->data.fn.fn_type_id; 12619 if (parent_fn_type->cc != CallingConventionAsync) { 12620 ir_add_error(ira, source_instr, buf_sprintf("async function call from non-async caller requires allocator parameter")); 12621 return ira->codegen->invalid_instruction; 12622 } 12623 12624 assert(parent_fn_type->async_allocator_type != nullptr); 12625 12626 switch (id) { 12627 case ImplicitAllocatorIdArg: 12628 { 12629 IrInstruction *result = ir_build_get_implicit_allocator(&ira->new_irb, source_instr->scope, 12630 source_instr->source_node, ImplicitAllocatorIdArg); 12631 result->value.type = parent_fn_type->async_allocator_type; 12632 return result; 12633 } 12634 case ImplicitAllocatorIdLocalVar: 12635 { 12636 ZigVar *coro_allocator_var = ira->old_irb.exec->coro_allocator_var; 12637 assert(coro_allocator_var != nullptr); 12638 IrInstruction *var_ptr_inst = ir_get_var_ptr(ira, source_instr, coro_allocator_var); 12639 IrInstruction *result = ir_get_deref(ira, source_instr, var_ptr_inst); 12640 assert(result->value.type != nullptr); 12641 return result; 12642 } 12643 } 12644 zig_unreachable(); 12645 } 12646 12647 static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCall *call_instruction, ZigFn *fn_entry, ZigType *fn_type, 12648 IrInstruction *fn_ref, IrInstruction **casted_args, size_t arg_count, IrInstruction *async_allocator_inst) 12649 { 12650 Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME); 12651 //Buf *free_field_name = buf_create_from_str("freeFn"); 12652 assert(async_allocator_inst->value.type->id == ZigTypeIdPointer); 12653 ZigType *container_type = async_allocator_inst->value.type->data.pointer.child_type; 12654 IrInstruction *field_ptr_inst = ir_analyze_container_field_ptr(ira, alloc_field_name, &call_instruction->base, 12655 async_allocator_inst, container_type); 12656 if (type_is_invalid(field_ptr_inst->value.type)) { 12657 return ira->codegen->invalid_instruction; 12658 } 12659 ZigType *ptr_to_alloc_fn_type = field_ptr_inst->value.type; 12660 assert(ptr_to_alloc_fn_type->id == ZigTypeIdPointer); 12661 12662 ZigType *alloc_fn_type = ptr_to_alloc_fn_type->data.pointer.child_type; 12663 if (alloc_fn_type->id != ZigTypeIdFn) { 12664 ir_add_error(ira, &call_instruction->base, 12665 buf_sprintf("expected allocation function, found '%s'", buf_ptr(&alloc_fn_type->name))); 12666 return ira->codegen->invalid_instruction; 12667 } 12668 12669 ZigType *alloc_fn_return_type = alloc_fn_type->data.fn.fn_type_id.return_type; 12670 if (alloc_fn_return_type->id != ZigTypeIdErrorUnion) { 12671 ir_add_error(ira, fn_ref, 12672 buf_sprintf("expected allocation function to return error union, but it returns '%s'", buf_ptr(&alloc_fn_return_type->name))); 12673 return ira->codegen->invalid_instruction; 12674 } 12675 ZigType *alloc_fn_error_set_type = alloc_fn_return_type->data.error_union.err_set_type; 12676 ZigType *return_type = fn_type->data.fn.fn_type_id.return_type; 12677 ZigType *promise_type = get_promise_type(ira->codegen, return_type); 12678 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type); 12679 12680 IrInstruction *result = ir_build_call(&ira->new_irb, call_instruction->base.scope, call_instruction->base.source_node, 12681 fn_entry, fn_ref, arg_count, casted_args, false, FnInlineAuto, true, async_allocator_inst, nullptr); 12682 result->value.type = async_return_type; 12683 return result; 12684 } 12685 12686 static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, 12687 IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) 12688 { 12689 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 12690 assert(param_decl_node->type == NodeTypeParamDecl); 12691 12692 IrInstruction *casted_arg; 12693 if (param_decl_node->data.param_decl.var_token == nullptr) { 12694 AstNode *param_type_node = param_decl_node->data.param_decl.type; 12695 ZigType *param_type = analyze_type_expr(ira->codegen, *exec_scope, param_type_node); 12696 if (type_is_invalid(param_type)) 12697 return false; 12698 12699 casted_arg = ir_implicit_cast(ira, arg, param_type); 12700 if (type_is_invalid(casted_arg->value.type)) 12701 return false; 12702 } else { 12703 casted_arg = arg; 12704 } 12705 12706 ConstExprValue *arg_val = ir_resolve_const(ira, casted_arg, UndefBad); 12707 if (!arg_val) 12708 return false; 12709 12710 Buf *param_name = param_decl_node->data.param_decl.name; 12711 ZigVar *var = add_variable(ira->codegen, param_decl_node, 12712 *exec_scope, param_name, true, arg_val, nullptr); 12713 *exec_scope = var->child_scope; 12714 *next_proto_i += 1; 12715 12716 return true; 12717 } 12718 12719 static bool ir_analyze_fn_call_generic_arg(IrAnalyze *ira, AstNode *fn_proto_node, 12720 IrInstruction *arg, Scope **child_scope, size_t *next_proto_i, 12721 GenericFnTypeId *generic_id, FnTypeId *fn_type_id, IrInstruction **casted_args, 12722 ZigFn *impl_fn) 12723 { 12724 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(*next_proto_i); 12725 assert(param_decl_node->type == NodeTypeParamDecl); 12726 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 12727 bool arg_part_of_generic_id = false; 12728 IrInstruction *casted_arg; 12729 if (is_var_args) { 12730 arg_part_of_generic_id = true; 12731 casted_arg = arg; 12732 } else { 12733 if (param_decl_node->data.param_decl.var_token == nullptr) { 12734 AstNode *param_type_node = param_decl_node->data.param_decl.type; 12735 ZigType *param_type = analyze_type_expr(ira->codegen, *child_scope, param_type_node); 12736 if (type_is_invalid(param_type)) 12737 return false; 12738 12739 casted_arg = ir_implicit_cast(ira, arg, param_type); 12740 if (type_is_invalid(casted_arg->value.type)) 12741 return false; 12742 } else { 12743 arg_part_of_generic_id = true; 12744 casted_arg = arg; 12745 } 12746 } 12747 12748 bool comptime_arg = param_decl_node->data.param_decl.is_inline || 12749 casted_arg->value.type->id == ZigTypeIdComptimeInt || casted_arg->value.type->id == ZigTypeIdComptimeFloat; 12750 12751 ConstExprValue *arg_val; 12752 12753 if (comptime_arg) { 12754 arg_part_of_generic_id = true; 12755 arg_val = ir_resolve_const(ira, casted_arg, UndefBad); 12756 if (!arg_val) 12757 return false; 12758 } else { 12759 arg_val = create_const_runtime(casted_arg->value.type); 12760 } 12761 if (arg_part_of_generic_id) { 12762 generic_id->params[generic_id->param_count] = *arg_val; 12763 generic_id->param_count += 1; 12764 } 12765 12766 Buf *param_name = param_decl_node->data.param_decl.name; 12767 if (!param_name) return false; 12768 if (!is_var_args) { 12769 ZigVar *var = add_variable(ira->codegen, param_decl_node, 12770 *child_scope, param_name, true, arg_val, nullptr); 12771 *child_scope = var->child_scope; 12772 var->shadowable = !comptime_arg; 12773 12774 *next_proto_i += 1; 12775 } else if (casted_arg->value.type->id == ZigTypeIdComptimeInt || 12776 casted_arg->value.type->id == ZigTypeIdComptimeFloat) 12777 { 12778 ir_add_error(ira, casted_arg, 12779 buf_sprintf("compiler bug: integer and float literals in var args function must be casted. https://github.com/ziglang/zig/issues/557")); 12780 return false; 12781 } 12782 12783 if (!comptime_arg) { 12784 if (type_requires_comptime(casted_arg->value.type)) { 12785 ir_add_error(ira, casted_arg, 12786 buf_sprintf("parameter of type '%s' requires comptime", buf_ptr(&casted_arg->value.type->name))); 12787 return false; 12788 } 12789 12790 casted_args[fn_type_id->param_count] = casted_arg; 12791 FnTypeParamInfo *param_info = &fn_type_id->param_info[fn_type_id->param_count]; 12792 param_info->type = casted_arg->value.type; 12793 param_info->is_noalias = param_decl_node->data.param_decl.is_noalias; 12794 impl_fn->param_source_nodes[fn_type_id->param_count] = param_decl_node; 12795 fn_type_id->param_count += 1; 12796 } 12797 12798 return true; 12799 } 12800 12801 static ZigVar *get_fn_var_by_index(ZigFn *fn_entry, size_t index) { 12802 size_t next_var_i = 0; 12803 FnGenParamInfo *gen_param_info = fn_entry->type_entry->data.fn.gen_param_info; 12804 assert(gen_param_info != nullptr); 12805 for (size_t param_i = 0; param_i < index; param_i += 1) { 12806 FnGenParamInfo *info = &gen_param_info[param_i]; 12807 if (info->gen_index == SIZE_MAX) 12808 continue; 12809 12810 next_var_i += 1; 12811 } 12812 FnGenParamInfo *info = &gen_param_info[index]; 12813 if (info->gen_index == SIZE_MAX) 12814 return nullptr; 12815 12816 return fn_entry->variable_list.at(next_var_i); 12817 } 12818 12819 static IrInstruction *ir_get_var_ptr(IrAnalyze *ira, IrInstruction *instruction, 12820 ZigVar *var) 12821 { 12822 while (var->next_var != nullptr) { 12823 var = var->next_var; 12824 } 12825 12826 if (var->mem_slot_index != SIZE_MAX && var->owner_exec->analysis == nullptr) { 12827 assert(ira->codegen->errors.length != 0); 12828 return ira->codegen->invalid_instruction; 12829 } 12830 if (var->value->type == nullptr || type_is_invalid(var->value->type)) 12831 return ira->codegen->invalid_instruction; 12832 12833 bool comptime_var_mem = ir_get_var_is_comptime(var); 12834 12835 ConstExprValue *mem_slot = nullptr; 12836 if (var->value->special == ConstValSpecialStatic) { 12837 mem_slot = var->value; 12838 } else { 12839 if (var->mem_slot_index != SIZE_MAX && (comptime_var_mem || var->gen_is_const)) { 12840 // find the relevant exec_context 12841 assert(var->owner_exec != nullptr); 12842 assert(var->owner_exec->analysis != nullptr); 12843 IrExecContext *exec_context = &var->owner_exec->analysis->exec_context; 12844 assert(var->mem_slot_index < exec_context->mem_slot_list.length); 12845 mem_slot = exec_context->mem_slot_list.at(var->mem_slot_index); 12846 } 12847 } 12848 12849 bool is_const = var->src_is_const; 12850 bool is_volatile = false; 12851 if (mem_slot != nullptr) { 12852 switch (mem_slot->special) { 12853 case ConstValSpecialRuntime: 12854 goto no_mem_slot; 12855 case ConstValSpecialStatic: // fallthrough 12856 case ConstValSpecialUndef: { 12857 ConstPtrMut ptr_mut; 12858 if (comptime_var_mem) { 12859 ptr_mut = ConstPtrMutComptimeVar; 12860 } else if (var->gen_is_const) { 12861 ptr_mut = ConstPtrMutComptimeConst; 12862 } else { 12863 assert(!comptime_var_mem); 12864 ptr_mut = ConstPtrMutRuntimeVar; 12865 } 12866 return ir_get_const_ptr(ira, instruction, mem_slot, var->value->type, 12867 ptr_mut, is_const, is_volatile, var->align_bytes); 12868 } 12869 } 12870 zig_unreachable(); 12871 } 12872 12873 no_mem_slot: 12874 12875 IrInstruction *var_ptr_instruction = ir_build_var_ptr(&ira->new_irb, 12876 instruction->scope, instruction->source_node, var); 12877 var_ptr_instruction->value.type = get_pointer_to_type_extra(ira->codegen, var->value->type, 12878 var->src_is_const, is_volatile, PtrLenSingle, var->align_bytes, 0, 0); 12879 12880 bool in_fn_scope = (scope_fn_entry(var->parent_scope) != nullptr); 12881 var_ptr_instruction->value.data.rh_ptr = in_fn_scope ? RuntimeHintPtrStack : RuntimeHintPtrNonStack; 12882 12883 return var_ptr_instruction; 12884 } 12885 12886 static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCall *call_instruction, 12887 ZigFn *fn_entry, ZigType *fn_type, IrInstruction *fn_ref, 12888 IrInstruction *first_arg_ptr, bool comptime_fn_call, FnInline fn_inline) 12889 { 12890 Error err; 12891 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 12892 size_t first_arg_1_or_0 = first_arg_ptr ? 1 : 0; 12893 12894 // for extern functions, the var args argument is not counted. 12895 // for zig functions, it is. 12896 size_t var_args_1_or_0; 12897 if (fn_type_id->cc == CallingConventionC) { 12898 var_args_1_or_0 = 0; 12899 } else { 12900 var_args_1_or_0 = fn_type_id->is_var_args ? 1 : 0; 12901 } 12902 size_t src_param_count = fn_type_id->param_count - var_args_1_or_0; 12903 12904 size_t call_param_count = call_instruction->arg_count + first_arg_1_or_0; 12905 for (size_t i = 0; i < call_instruction->arg_count; i += 1) { 12906 ConstExprValue *arg_tuple_value = &call_instruction->args[i]->child->value; 12907 if (arg_tuple_value->type->id == ZigTypeIdArgTuple) { 12908 call_param_count -= 1; 12909 call_param_count += arg_tuple_value->data.x_arg_tuple.end_index - 12910 arg_tuple_value->data.x_arg_tuple.start_index; 12911 } 12912 } 12913 AstNode *source_node = call_instruction->base.source_node; 12914 12915 AstNode *fn_proto_node = fn_entry ? fn_entry->proto_node : nullptr;; 12916 12917 if (fn_type_id->cc == CallingConventionNaked) { 12918 ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("unable to call function with naked calling convention")); 12919 if (fn_proto_node) { 12920 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 12921 } 12922 return ira->codegen->invalid_instruction; 12923 } 12924 if (fn_type_id->cc == CallingConventionAsync && !call_instruction->is_async) { 12925 ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("must use async keyword to call async function")); 12926 if (fn_proto_node) { 12927 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 12928 } 12929 return ira->codegen->invalid_instruction; 12930 } 12931 if (fn_type_id->cc != CallingConventionAsync && call_instruction->is_async) { 12932 ErrorMsg *msg = ir_add_error(ira, fn_ref, buf_sprintf("cannot use async keyword to call non-async function")); 12933 if (fn_proto_node) { 12934 add_error_note(ira->codegen, msg, fn_proto_node, buf_sprintf("declared here")); 12935 } 12936 return ira->codegen->invalid_instruction; 12937 } 12938 12939 12940 if (fn_type_id->is_var_args) { 12941 if (call_param_count < src_param_count) { 12942 ErrorMsg *msg = ir_add_error_node(ira, source_node, 12943 buf_sprintf("expected at least %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 12944 if (fn_proto_node) { 12945 add_error_note(ira->codegen, msg, fn_proto_node, 12946 buf_sprintf("declared here")); 12947 } 12948 return ira->codegen->invalid_instruction; 12949 } 12950 } else if (src_param_count != call_param_count) { 12951 ErrorMsg *msg = ir_add_error_node(ira, source_node, 12952 buf_sprintf("expected %" ZIG_PRI_usize " arguments, found %" ZIG_PRI_usize "", src_param_count, call_param_count)); 12953 if (fn_proto_node) { 12954 add_error_note(ira->codegen, msg, fn_proto_node, 12955 buf_sprintf("declared here")); 12956 } 12957 return ira->codegen->invalid_instruction; 12958 } 12959 12960 if (comptime_fn_call) { 12961 // No special handling is needed for compile time evaluation of generic functions. 12962 if (!fn_entry || fn_entry->body_node == nullptr) { 12963 ir_add_error(ira, fn_ref, buf_sprintf("unable to evaluate constant expression")); 12964 return ira->codegen->invalid_instruction; 12965 } 12966 12967 if (!ir_emit_backward_branch(ira, &call_instruction->base)) 12968 return ira->codegen->invalid_instruction; 12969 12970 // Fork a scope of the function with known values for the parameters. 12971 Scope *exec_scope = &fn_entry->fndef_scope->base; 12972 12973 size_t next_proto_i = 0; 12974 if (first_arg_ptr) { 12975 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 12976 12977 bool first_arg_known_bare = false; 12978 if (fn_type_id->next_param_index >= 1) { 12979 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 12980 if (type_is_invalid(param_type)) 12981 return ira->codegen->invalid_instruction; 12982 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 12983 } 12984 12985 IrInstruction *first_arg; 12986 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { 12987 first_arg = first_arg_ptr; 12988 } else { 12989 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); 12990 if (type_is_invalid(first_arg->value.type)) 12991 return ira->codegen->invalid_instruction; 12992 } 12993 12994 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, first_arg, &exec_scope, &next_proto_i)) 12995 return ira->codegen->invalid_instruction; 12996 } 12997 12998 if (fn_proto_node->data.fn_proto.is_var_args) { 12999 ir_add_error(ira, &call_instruction->base, 13000 buf_sprintf("compiler bug: unable to call var args function at compile time. https://github.com/ziglang/zig/issues/313")); 13001 return ira->codegen->invalid_instruction; 13002 } 13003 13004 13005 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 13006 IrInstruction *old_arg = call_instruction->args[call_i]->child; 13007 if (type_is_invalid(old_arg->value.type)) 13008 return ira->codegen->invalid_instruction; 13009 13010 if (!ir_analyze_fn_call_inline_arg(ira, fn_proto_node, old_arg, &exec_scope, &next_proto_i)) 13011 return ira->codegen->invalid_instruction; 13012 } 13013 13014 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 13015 ZigType *specified_return_type = analyze_type_expr(ira->codegen, exec_scope, return_type_node); 13016 if (type_is_invalid(specified_return_type)) 13017 return ira->codegen->invalid_instruction; 13018 ZigType *return_type; 13019 ZigType *inferred_err_set_type = nullptr; 13020 if (fn_proto_node->data.fn_proto.auto_err_set) { 13021 inferred_err_set_type = get_auto_err_set_type(ira->codegen, fn_entry); 13022 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 13023 return ira->codegen->invalid_instruction; 13024 return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 13025 } else { 13026 return_type = specified_return_type; 13027 } 13028 13029 bool cacheable = fn_eval_cacheable(exec_scope, return_type); 13030 IrInstruction *result = nullptr; 13031 if (cacheable) { 13032 auto entry = ira->codegen->memoized_fn_eval_table.maybe_get(exec_scope); 13033 if (entry) 13034 result = entry->value; 13035 } 13036 13037 if (result == nullptr) { 13038 // Analyze the fn body block like any other constant expression. 13039 AstNode *body_node = fn_entry->body_node; 13040 result = ir_eval_const_value(ira->codegen, exec_scope, body_node, return_type, 13041 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, fn_entry, 13042 nullptr, call_instruction->base.source_node, nullptr, ira->new_irb.exec); 13043 13044 if (inferred_err_set_type != nullptr) { 13045 inferred_err_set_type->data.error_set.infer_fn = nullptr; 13046 if (result->value.type->id == ZigTypeIdErrorUnion) { 13047 if (result->value.data.x_err_union.err != nullptr) { 13048 inferred_err_set_type->data.error_set.err_count = 1; 13049 inferred_err_set_type->data.error_set.errors = allocate<ErrorTableEntry *>(1); 13050 inferred_err_set_type->data.error_set.errors[0] = result->value.data.x_err_union.err; 13051 } 13052 ZigType *fn_inferred_err_set_type = result->value.type->data.error_union.err_set_type; 13053 inferred_err_set_type->data.error_set.err_count = fn_inferred_err_set_type->data.error_set.err_count; 13054 inferred_err_set_type->data.error_set.errors = fn_inferred_err_set_type->data.error_set.errors; 13055 } else if (result->value.type->id == ZigTypeIdErrorSet) { 13056 inferred_err_set_type->data.error_set.err_count = result->value.type->data.error_set.err_count; 13057 inferred_err_set_type->data.error_set.errors = result->value.type->data.error_set.errors; 13058 } 13059 } 13060 13061 if (cacheable) { 13062 ira->codegen->memoized_fn_eval_table.put(exec_scope, result); 13063 } 13064 13065 if (type_is_invalid(result->value.type)) 13066 return ira->codegen->invalid_instruction; 13067 } 13068 13069 IrInstruction *new_instruction = ir_const(ira, &call_instruction->base, result->value.type); 13070 // TODO should we use copy_const_val? 13071 new_instruction->value = result->value; 13072 new_instruction->value.type = return_type; 13073 return ir_finish_anal(ira, new_instruction); 13074 } 13075 13076 IrInstruction *casted_new_stack = nullptr; 13077 if (call_instruction->new_stack != nullptr) { 13078 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 13079 false, false, PtrLenUnknown, 0, 0, 0); 13080 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 13081 IrInstruction *new_stack = call_instruction->new_stack->child; 13082 if (type_is_invalid(new_stack->value.type)) 13083 return ira->codegen->invalid_instruction; 13084 13085 casted_new_stack = ir_implicit_cast(ira, new_stack, u8_slice); 13086 if (type_is_invalid(casted_new_stack->value.type)) 13087 return ira->codegen->invalid_instruction; 13088 } 13089 13090 if (fn_type->data.fn.is_generic) { 13091 if (!fn_entry) { 13092 ir_add_error(ira, call_instruction->fn_ref, 13093 buf_sprintf("calling a generic function requires compile-time known function value")); 13094 return ira->codegen->invalid_instruction; 13095 } 13096 13097 // Count the arguments of the function type id we are creating 13098 size_t new_fn_arg_count = first_arg_1_or_0; 13099 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 13100 IrInstruction *arg = call_instruction->args[call_i]->child; 13101 if (type_is_invalid(arg->value.type)) 13102 return ira->codegen->invalid_instruction; 13103 13104 if (arg->value.type->id == ZigTypeIdArgTuple) { 13105 new_fn_arg_count += arg->value.data.x_arg_tuple.end_index - arg->value.data.x_arg_tuple.start_index; 13106 } else { 13107 new_fn_arg_count += 1; 13108 } 13109 } 13110 13111 IrInstruction **casted_args = allocate<IrInstruction *>(new_fn_arg_count); 13112 13113 // Fork a scope of the function with known values for the parameters. 13114 Scope *parent_scope = fn_entry->fndef_scope->base.parent; 13115 ZigFn *impl_fn = create_fn(ira->codegen, fn_proto_node); 13116 impl_fn->param_source_nodes = allocate<AstNode *>(new_fn_arg_count); 13117 buf_init_from_buf(&impl_fn->symbol_name, &fn_entry->symbol_name); 13118 impl_fn->fndef_scope = create_fndef_scope(ira->codegen, impl_fn->body_node, parent_scope, impl_fn); 13119 impl_fn->child_scope = &impl_fn->fndef_scope->base; 13120 FnTypeId inst_fn_type_id = {0}; 13121 init_fn_type_id(&inst_fn_type_id, fn_proto_node, new_fn_arg_count); 13122 inst_fn_type_id.param_count = 0; 13123 inst_fn_type_id.is_var_args = false; 13124 13125 // TODO maybe GenericFnTypeId can be replaced with using the child_scope directly 13126 // as the key in generic_table 13127 GenericFnTypeId *generic_id = allocate<GenericFnTypeId>(1); 13128 generic_id->fn_entry = fn_entry; 13129 generic_id->param_count = 0; 13130 generic_id->params = create_const_vals(new_fn_arg_count); 13131 size_t next_proto_i = 0; 13132 13133 if (first_arg_ptr) { 13134 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 13135 13136 bool first_arg_known_bare = false; 13137 if (fn_type_id->next_param_index >= 1) { 13138 ZigType *param_type = fn_type_id->param_info[next_proto_i].type; 13139 if (type_is_invalid(param_type)) 13140 return ira->codegen->invalid_instruction; 13141 first_arg_known_bare = param_type->id != ZigTypeIdPointer; 13142 } 13143 13144 IrInstruction *first_arg; 13145 if (!first_arg_known_bare && handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) { 13146 first_arg = first_arg_ptr; 13147 } else { 13148 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); 13149 if (type_is_invalid(first_arg->value.type)) 13150 return ira->codegen->invalid_instruction; 13151 } 13152 13153 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, first_arg, &impl_fn->child_scope, 13154 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 13155 { 13156 return ira->codegen->invalid_instruction; 13157 } 13158 } 13159 13160 bool found_first_var_arg = false; 13161 size_t first_var_arg; 13162 13163 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 13164 assert(parent_fn_entry); 13165 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 13166 IrInstruction *arg = call_instruction->args[call_i]->child; 13167 if (type_is_invalid(arg->value.type)) 13168 return ira->codegen->invalid_instruction; 13169 13170 if (arg->value.type->id == ZigTypeIdArgTuple) { 13171 for (size_t arg_tuple_i = arg->value.data.x_arg_tuple.start_index; 13172 arg_tuple_i < arg->value.data.x_arg_tuple.end_index; arg_tuple_i += 1) 13173 { 13174 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 13175 assert(param_decl_node->type == NodeTypeParamDecl); 13176 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 13177 if (is_var_args && !found_first_var_arg) { 13178 first_var_arg = inst_fn_type_id.param_count; 13179 found_first_var_arg = true; 13180 } 13181 13182 ZigVar *arg_var = get_fn_var_by_index(parent_fn_entry, arg_tuple_i); 13183 if (arg_var == nullptr) { 13184 ir_add_error(ira, arg, 13185 buf_sprintf("compiler bug: var args can't handle void. https://github.com/ziglang/zig/issues/557")); 13186 return ira->codegen->invalid_instruction; 13187 } 13188 IrInstruction *arg_var_ptr_inst = ir_get_var_ptr(ira, arg, arg_var); 13189 if (type_is_invalid(arg_var_ptr_inst->value.type)) 13190 return ira->codegen->invalid_instruction; 13191 13192 IrInstruction *arg_tuple_arg = ir_get_deref(ira, arg, arg_var_ptr_inst); 13193 if (type_is_invalid(arg_tuple_arg->value.type)) 13194 return ira->codegen->invalid_instruction; 13195 13196 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg_tuple_arg, &impl_fn->child_scope, 13197 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 13198 { 13199 return ira->codegen->invalid_instruction; 13200 } 13201 } 13202 } else { 13203 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 13204 assert(param_decl_node->type == NodeTypeParamDecl); 13205 bool is_var_args = param_decl_node->data.param_decl.is_var_args; 13206 if (is_var_args && !found_first_var_arg) { 13207 first_var_arg = inst_fn_type_id.param_count; 13208 found_first_var_arg = true; 13209 } 13210 13211 if (!ir_analyze_fn_call_generic_arg(ira, fn_proto_node, arg, &impl_fn->child_scope, 13212 &next_proto_i, generic_id, &inst_fn_type_id, casted_args, impl_fn)) 13213 { 13214 return ira->codegen->invalid_instruction; 13215 } 13216 } 13217 } 13218 13219 if (fn_proto_node->data.fn_proto.is_var_args) { 13220 AstNode *param_decl_node = fn_proto_node->data.fn_proto.params.at(next_proto_i); 13221 Buf *param_name = param_decl_node->data.param_decl.name; 13222 13223 if (!found_first_var_arg) { 13224 first_var_arg = inst_fn_type_id.param_count; 13225 } 13226 13227 ConstExprValue *var_args_val = create_const_arg_tuple(ira->codegen, 13228 first_var_arg, inst_fn_type_id.param_count); 13229 ZigVar *var = add_variable(ira->codegen, param_decl_node, 13230 impl_fn->child_scope, param_name, true, var_args_val, nullptr); 13231 impl_fn->child_scope = var->child_scope; 13232 } 13233 13234 if (fn_proto_node->data.fn_proto.align_expr != nullptr) { 13235 IrInstruction *align_result = ir_eval_const_value(ira->codegen, impl_fn->child_scope, 13236 fn_proto_node->data.fn_proto.align_expr, get_align_amt_type(ira->codegen), 13237 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, 13238 nullptr, nullptr, fn_proto_node->data.fn_proto.align_expr, nullptr, ira->new_irb.exec); 13239 13240 uint32_t align_bytes = 0; 13241 ir_resolve_align(ira, align_result, &align_bytes); 13242 impl_fn->align_bytes = align_bytes; 13243 inst_fn_type_id.alignment = align_bytes; 13244 } 13245 13246 if (fn_proto_node->data.fn_proto.return_var_token == nullptr) { 13247 AstNode *return_type_node = fn_proto_node->data.fn_proto.return_type; 13248 ZigType *specified_return_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, return_type_node); 13249 if (type_is_invalid(specified_return_type)) 13250 return ira->codegen->invalid_instruction; 13251 if (fn_proto_node->data.fn_proto.auto_err_set) { 13252 ZigType *inferred_err_set_type = get_auto_err_set_type(ira->codegen, impl_fn); 13253 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusSizeKnown))) 13254 return ira->codegen->invalid_instruction; 13255 inst_fn_type_id.return_type = get_error_union_type(ira->codegen, inferred_err_set_type, specified_return_type); 13256 } else { 13257 inst_fn_type_id.return_type = specified_return_type; 13258 } 13259 13260 if ((err = type_resolve(ira->codegen, specified_return_type, ResolveStatusZeroBitsKnown))) 13261 return ira->codegen->invalid_instruction; 13262 13263 if (type_requires_comptime(specified_return_type)) { 13264 // Throw out our work and call the function as if it were comptime. 13265 return ir_analyze_fn_call(ira, call_instruction, fn_entry, fn_type, fn_ref, first_arg_ptr, true, FnInlineAuto); 13266 } 13267 } 13268 IrInstruction *async_allocator_inst = nullptr; 13269 if (call_instruction->is_async) { 13270 AstNode *async_allocator_type_node = fn_proto_node->data.fn_proto.async_allocator_type; 13271 if (async_allocator_type_node != nullptr) { 13272 ZigType *async_allocator_type = analyze_type_expr(ira->codegen, impl_fn->child_scope, async_allocator_type_node); 13273 if (type_is_invalid(async_allocator_type)) 13274 return ira->codegen->invalid_instruction; 13275 inst_fn_type_id.async_allocator_type = async_allocator_type; 13276 } 13277 IrInstruction *uncasted_async_allocator_inst; 13278 if (call_instruction->async_allocator == nullptr) { 13279 uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, 13280 ImplicitAllocatorIdLocalVar); 13281 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 13282 return ira->codegen->invalid_instruction; 13283 } else { 13284 uncasted_async_allocator_inst = call_instruction->async_allocator->child; 13285 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 13286 return ira->codegen->invalid_instruction; 13287 } 13288 if (inst_fn_type_id.async_allocator_type == nullptr) { 13289 inst_fn_type_id.async_allocator_type = uncasted_async_allocator_inst->value.type; 13290 } 13291 async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, inst_fn_type_id.async_allocator_type); 13292 if (type_is_invalid(async_allocator_inst->value.type)) 13293 return ira->codegen->invalid_instruction; 13294 } 13295 13296 auto existing_entry = ira->codegen->generic_table.put_unique(generic_id, impl_fn); 13297 if (existing_entry) { 13298 // throw away all our work and use the existing function 13299 impl_fn = existing_entry->value; 13300 } else { 13301 // finish instantiating the function 13302 impl_fn->type_entry = get_fn_type(ira->codegen, &inst_fn_type_id); 13303 if (type_is_invalid(impl_fn->type_entry)) 13304 return ira->codegen->invalid_instruction; 13305 13306 impl_fn->ir_executable.source_node = call_instruction->base.source_node; 13307 impl_fn->ir_executable.parent_exec = ira->new_irb.exec; 13308 impl_fn->analyzed_executable.source_node = call_instruction->base.source_node; 13309 impl_fn->analyzed_executable.parent_exec = ira->new_irb.exec; 13310 impl_fn->analyzed_executable.backward_branch_quota = ira->new_irb.exec->backward_branch_quota; 13311 impl_fn->analyzed_executable.is_generic_instantiation = true; 13312 13313 ira->codegen->fn_defs.append(impl_fn); 13314 } 13315 13316 ZigType *return_type = impl_fn->type_entry->data.fn.fn_type_id.return_type; 13317 if (fn_type_can_fail(&impl_fn->type_entry->data.fn.fn_type_id)) { 13318 parent_fn_entry->calls_or_awaits_errorable_fn = true; 13319 } 13320 13321 size_t impl_param_count = impl_fn->type_entry->data.fn.fn_type_id.param_count; 13322 if (call_instruction->is_async) { 13323 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, impl_fn, impl_fn->type_entry, 13324 fn_ref, casted_args, impl_param_count, async_allocator_inst); 13325 ir_add_alloca(ira, result, result->value.type); 13326 return ir_finish_anal(ira, result); 13327 } 13328 13329 assert(async_allocator_inst == nullptr); 13330 IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, 13331 call_instruction->base.scope, call_instruction->base.source_node, 13332 impl_fn, nullptr, impl_param_count, casted_args, false, fn_inline, 13333 call_instruction->is_async, nullptr, casted_new_stack); 13334 new_call_instruction->value.type = return_type; 13335 13336 ir_add_alloca(ira, new_call_instruction, return_type); 13337 13338 return ir_finish_anal(ira, new_call_instruction); 13339 } 13340 13341 ZigFn *parent_fn_entry = exec_fn_entry(ira->new_irb.exec); 13342 assert(fn_type_id->return_type != nullptr); 13343 assert(parent_fn_entry != nullptr); 13344 if (fn_type_can_fail(fn_type_id)) { 13345 parent_fn_entry->calls_or_awaits_errorable_fn = true; 13346 } 13347 13348 13349 IrInstruction **casted_args = allocate<IrInstruction *>(call_param_count); 13350 size_t next_arg_index = 0; 13351 if (first_arg_ptr) { 13352 assert(first_arg_ptr->value.type->id == ZigTypeIdPointer); 13353 13354 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 13355 if (type_is_invalid(param_type)) 13356 return ira->codegen->invalid_instruction; 13357 13358 IrInstruction *first_arg; 13359 if (param_type->id == ZigTypeIdPointer && 13360 handle_is_ptr(first_arg_ptr->value.type->data.pointer.child_type)) 13361 { 13362 first_arg = first_arg_ptr; 13363 } else { 13364 first_arg = ir_get_deref(ira, first_arg_ptr, first_arg_ptr); 13365 if (type_is_invalid(first_arg->value.type)) 13366 return ira->codegen->invalid_instruction; 13367 } 13368 13369 IrInstruction *casted_arg = ir_implicit_cast(ira, first_arg, param_type); 13370 if (type_is_invalid(casted_arg->value.type)) 13371 return ira->codegen->invalid_instruction; 13372 13373 casted_args[next_arg_index] = casted_arg; 13374 next_arg_index += 1; 13375 } 13376 for (size_t call_i = 0; call_i < call_instruction->arg_count; call_i += 1) { 13377 IrInstruction *old_arg = call_instruction->args[call_i]->child; 13378 if (type_is_invalid(old_arg->value.type)) 13379 return ira->codegen->invalid_instruction; 13380 IrInstruction *casted_arg; 13381 if (next_arg_index < src_param_count) { 13382 ZigType *param_type = fn_type_id->param_info[next_arg_index].type; 13383 if (type_is_invalid(param_type)) 13384 return ira->codegen->invalid_instruction; 13385 casted_arg = ir_implicit_cast(ira, old_arg, param_type); 13386 if (type_is_invalid(casted_arg->value.type)) 13387 return ira->codegen->invalid_instruction; 13388 } else { 13389 casted_arg = old_arg; 13390 } 13391 13392 casted_args[next_arg_index] = casted_arg; 13393 next_arg_index += 1; 13394 } 13395 13396 assert(next_arg_index == call_param_count); 13397 13398 ZigType *return_type = fn_type_id->return_type; 13399 if (type_is_invalid(return_type)) 13400 return ira->codegen->invalid_instruction; 13401 13402 if (call_instruction->is_async) { 13403 IrInstruction *uncasted_async_allocator_inst; 13404 if (call_instruction->async_allocator == nullptr) { 13405 uncasted_async_allocator_inst = ir_get_implicit_allocator(ira, &call_instruction->base, 13406 ImplicitAllocatorIdLocalVar); 13407 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 13408 return ira->codegen->invalid_instruction; 13409 } else { 13410 uncasted_async_allocator_inst = call_instruction->async_allocator->child; 13411 if (type_is_invalid(uncasted_async_allocator_inst->value.type)) 13412 return ira->codegen->invalid_instruction; 13413 13414 } 13415 IrInstruction *async_allocator_inst = ir_implicit_cast(ira, uncasted_async_allocator_inst, fn_type_id->async_allocator_type); 13416 if (type_is_invalid(async_allocator_inst->value.type)) 13417 return ira->codegen->invalid_instruction; 13418 13419 IrInstruction *result = ir_analyze_async_call(ira, call_instruction, fn_entry, fn_type, fn_ref, 13420 casted_args, call_param_count, async_allocator_inst); 13421 ir_add_alloca(ira, result, result->value.type); 13422 return ir_finish_anal(ira, result); 13423 } 13424 13425 if (fn_entry != nullptr && fn_entry->fn_inline == FnInlineAlways && fn_inline == FnInlineNever) { 13426 ir_add_error(ira, &call_instruction->base, 13427 buf_sprintf("no-inline call of inline function")); 13428 return ira->codegen->invalid_instruction; 13429 } 13430 13431 IrInstruction *new_call_instruction = ir_build_call(&ira->new_irb, 13432 call_instruction->base.scope, call_instruction->base.source_node, 13433 fn_entry, fn_ref, call_param_count, casted_args, false, fn_inline, false, nullptr, casted_new_stack); 13434 new_call_instruction->value.type = return_type; 13435 ir_add_alloca(ira, new_call_instruction, return_type); 13436 return ir_finish_anal(ira, new_call_instruction); 13437 } 13438 13439 static IrInstruction *ir_analyze_instruction_call(IrAnalyze *ira, IrInstructionCall *call_instruction) { 13440 IrInstruction *fn_ref = call_instruction->fn_ref->child; 13441 if (type_is_invalid(fn_ref->value.type)) 13442 return ira->codegen->invalid_instruction; 13443 13444 bool is_comptime = call_instruction->is_comptime || 13445 ir_should_inline(ira->new_irb.exec, call_instruction->base.scope); 13446 13447 if (is_comptime || instr_is_comptime(fn_ref)) { 13448 if (fn_ref->value.type->id == ZigTypeIdMetaType) { 13449 ZigType *dest_type = ir_resolve_type(ira, fn_ref); 13450 if (type_is_invalid(dest_type)) 13451 return ira->codegen->invalid_instruction; 13452 13453 size_t actual_param_count = call_instruction->arg_count; 13454 13455 if (actual_param_count != 1) { 13456 ir_add_error_node(ira, call_instruction->base.source_node, 13457 buf_sprintf("cast expression expects exactly one parameter")); 13458 return ira->codegen->invalid_instruction; 13459 } 13460 13461 IrInstruction *arg = call_instruction->args[0]->child; 13462 13463 IrInstruction *cast_instruction = ir_analyze_cast(ira, &call_instruction->base, dest_type, arg); 13464 if (type_is_invalid(cast_instruction->value.type)) 13465 return ira->codegen->invalid_instruction; 13466 return ir_finish_anal(ira, cast_instruction); 13467 } else if (fn_ref->value.type->id == ZigTypeIdFn) { 13468 ZigFn *fn_table_entry = ir_resolve_fn(ira, fn_ref); 13469 if (fn_table_entry == nullptr) 13470 return ira->codegen->invalid_instruction; 13471 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 13472 fn_ref, nullptr, is_comptime, call_instruction->fn_inline); 13473 } else if (fn_ref->value.type->id == ZigTypeIdBoundFn) { 13474 assert(fn_ref->value.special == ConstValSpecialStatic); 13475 ZigFn *fn_table_entry = fn_ref->value.data.x_bound_fn.fn; 13476 IrInstruction *first_arg_ptr = fn_ref->value.data.x_bound_fn.first_arg; 13477 return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, 13478 fn_ref, first_arg_ptr, is_comptime, call_instruction->fn_inline); 13479 } else { 13480 ir_add_error_node(ira, fn_ref->source_node, 13481 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value.type->name))); 13482 return ira->codegen->invalid_instruction; 13483 } 13484 } 13485 13486 if (fn_ref->value.type->id == ZigTypeIdFn) { 13487 return ir_analyze_fn_call(ira, call_instruction, nullptr, fn_ref->value.type, 13488 fn_ref, nullptr, false, FnInlineAuto); 13489 } else { 13490 ir_add_error_node(ira, fn_ref->source_node, 13491 buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value.type->name))); 13492 return ira->codegen->invalid_instruction; 13493 } 13494 } 13495 13496 // out_val->type must be the type to read the pointer as 13497 // if the type is different than the actual type then it does a comptime byte reinterpretation 13498 static Error ir_read_const_ptr(IrAnalyze *ira, AstNode *source_node, 13499 ConstExprValue *out_val, ConstExprValue *ptr_val) 13500 { 13501 Error err; 13502 assert(out_val->type != nullptr); 13503 13504 ConstExprValue *pointee = const_ptr_pointee_unchecked(ira->codegen, ptr_val); 13505 13506 if ((err = type_resolve(ira->codegen, pointee->type, ResolveStatusSizeKnown))) 13507 return ErrorSemanticAnalyzeFail; 13508 if ((err = type_resolve(ira->codegen, out_val->type, ResolveStatusSizeKnown))) 13509 return ErrorSemanticAnalyzeFail; 13510 13511 size_t src_size = type_size(ira->codegen, pointee->type); 13512 size_t dst_size = type_size(ira->codegen, out_val->type); 13513 13514 if (src_size == dst_size && types_have_same_zig_comptime_repr(pointee->type, out_val->type)) { 13515 copy_const_val(out_val, pointee, ptr_val->data.x_ptr.mut == ConstPtrMutComptimeConst); 13516 return ErrorNone; 13517 } 13518 13519 if (dst_size > src_size) { 13520 ir_add_error_node(ira, source_node, 13521 buf_sprintf("attempt to read %zu bytes from pointer to %s which is %zu bytes", 13522 dst_size, buf_ptr(&pointee->type->name), src_size)); 13523 return ErrorSemanticAnalyzeFail; 13524 } 13525 13526 Buf buf = BUF_INIT; 13527 buf_resize(&buf, src_size); 13528 buf_write_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), pointee); 13529 buf_read_value_bytes(ira->codegen, (uint8_t*)buf_ptr(&buf), out_val); 13530 return ErrorNone; 13531 } 13532 13533 static IrInstruction *ir_analyze_maybe(IrAnalyze *ira, IrInstructionUnOp *un_op_instruction) { 13534 Error err; 13535 IrInstruction *value = un_op_instruction->value->child; 13536 ZigType *type_entry = ir_resolve_type(ira, value); 13537 if (type_is_invalid(type_entry)) 13538 return ira->codegen->invalid_instruction; 13539 if ((err = ensure_complete_type(ira->codegen, type_entry))) 13540 return ira->codegen->invalid_instruction; 13541 13542 switch (type_entry->id) { 13543 case ZigTypeIdInvalid: 13544 zig_unreachable(); 13545 case ZigTypeIdMetaType: 13546 case ZigTypeIdVoid: 13547 case ZigTypeIdBool: 13548 case ZigTypeIdInt: 13549 case ZigTypeIdFloat: 13550 case ZigTypeIdPointer: 13551 case ZigTypeIdArray: 13552 case ZigTypeIdStruct: 13553 case ZigTypeIdComptimeFloat: 13554 case ZigTypeIdComptimeInt: 13555 case ZigTypeIdUndefined: 13556 case ZigTypeIdNull: 13557 case ZigTypeIdOptional: 13558 case ZigTypeIdErrorUnion: 13559 case ZigTypeIdErrorSet: 13560 case ZigTypeIdEnum: 13561 case ZigTypeIdUnion: 13562 case ZigTypeIdFn: 13563 case ZigTypeIdNamespace: 13564 case ZigTypeIdBoundFn: 13565 case ZigTypeIdArgTuple: 13566 case ZigTypeIdPromise: 13567 return ir_const_type(ira, &un_op_instruction->base, get_optional_type(ira->codegen, type_entry)); 13568 case ZigTypeIdUnreachable: 13569 case ZigTypeIdOpaque: 13570 ir_add_error_node(ira, un_op_instruction->base.source_node, 13571 buf_sprintf("type '%s' not optional", buf_ptr(&type_entry->name))); 13572 return ira->codegen->invalid_instruction; 13573 } 13574 zig_unreachable(); 13575 } 13576 13577 static IrInstruction *ir_analyze_negation(IrAnalyze *ira, IrInstructionUnOp *instruction) { 13578 IrInstruction *value = instruction->value->child; 13579 ZigType *expr_type = value->value.type; 13580 if (type_is_invalid(expr_type)) 13581 return ira->codegen->invalid_instruction; 13582 13583 bool is_wrap_op = (instruction->op_id == IrUnOpNegationWrap); 13584 13585 bool is_float = (expr_type->id == ZigTypeIdFloat || expr_type->id == ZigTypeIdComptimeFloat); 13586 13587 if ((expr_type->id == ZigTypeIdInt && expr_type->data.integral.is_signed) || 13588 expr_type->id == ZigTypeIdComptimeInt || (is_float && !is_wrap_op)) 13589 { 13590 if (instr_is_comptime(value)) { 13591 ConstExprValue *target_const_val = ir_resolve_const(ira, value, UndefBad); 13592 if (!target_const_val) 13593 return ira->codegen->invalid_instruction; 13594 13595 IrInstruction *result = ir_const(ira, &instruction->base, expr_type); 13596 ConstExprValue *out_val = &result->value; 13597 if (is_float) { 13598 float_negate(out_val, target_const_val); 13599 } else if (is_wrap_op) { 13600 bigint_negate_wrap(&out_val->data.x_bigint, &target_const_val->data.x_bigint, 13601 expr_type->data.integral.bit_count); 13602 } else { 13603 bigint_negate(&out_val->data.x_bigint, &target_const_val->data.x_bigint); 13604 } 13605 if (is_wrap_op || is_float || expr_type->id == ZigTypeIdComptimeInt) { 13606 return result; 13607 } 13608 13609 if (!bigint_fits_in_bits(&out_val->data.x_bigint, expr_type->data.integral.bit_count, true)) { 13610 ir_add_error(ira, &instruction->base, buf_sprintf("negation caused overflow")); 13611 return ira->codegen->invalid_instruction; 13612 } 13613 return result; 13614 } 13615 13616 IrInstruction *result = ir_build_un_op(&ira->new_irb, 13617 instruction->base.scope, instruction->base.source_node, 13618 instruction->op_id, value); 13619 result->value.type = expr_type; 13620 return result; 13621 } 13622 13623 const char *fmt = is_wrap_op ? "invalid wrapping negation type: '%s'" : "invalid negation type: '%s'"; 13624 ir_add_error(ira, &instruction->base, buf_sprintf(fmt, buf_ptr(&expr_type->name))); 13625 return ira->codegen->invalid_instruction; 13626 } 13627 13628 static IrInstruction *ir_analyze_bin_not(IrAnalyze *ira, IrInstructionUnOp *instruction) { 13629 IrInstruction *value = instruction->value->child; 13630 ZigType *expr_type = value->value.type; 13631 if (type_is_invalid(expr_type)) 13632 return ira->codegen->invalid_instruction; 13633 13634 if (expr_type->id == ZigTypeIdInt) { 13635 if (instr_is_comptime(value)) { 13636 ConstExprValue *target_const_val = ir_resolve_const(ira, value, UndefBad); 13637 if (target_const_val == nullptr) 13638 return ira->codegen->invalid_instruction; 13639 13640 IrInstruction *result = ir_const(ira, &instruction->base, expr_type); 13641 bigint_not(&result->value.data.x_bigint, &target_const_val->data.x_bigint, 13642 expr_type->data.integral.bit_count, expr_type->data.integral.is_signed); 13643 return result; 13644 } 13645 13646 IrInstruction *result = ir_build_un_op(&ira->new_irb, instruction->base.scope, 13647 instruction->base.source_node, IrUnOpBinNot, value); 13648 result->value.type = expr_type; 13649 return result; 13650 } 13651 13652 ir_add_error(ira, &instruction->base, 13653 buf_sprintf("unable to perform binary not operation on type '%s'", buf_ptr(&expr_type->name))); 13654 return ira->codegen->invalid_instruction; 13655 } 13656 13657 static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstructionUnOp *instruction) { 13658 IrUnOp op_id = instruction->op_id; 13659 switch (op_id) { 13660 case IrUnOpInvalid: 13661 zig_unreachable(); 13662 case IrUnOpBinNot: 13663 return ir_analyze_bin_not(ira, instruction); 13664 case IrUnOpNegation: 13665 case IrUnOpNegationWrap: 13666 return ir_analyze_negation(ira, instruction); 13667 case IrUnOpDereference: { 13668 IrInstruction *ptr = instruction->value->child; 13669 if (type_is_invalid(ptr->value.type)) 13670 return ira->codegen->invalid_instruction; 13671 ZigType *ptr_type = ptr->value.type; 13672 if (ptr_type->id == ZigTypeIdPointer && ptr_type->data.pointer.ptr_len == PtrLenUnknown) { 13673 ir_add_error_node(ira, instruction->base.source_node, 13674 buf_sprintf("index syntax required for unknown-length pointer type '%s'", 13675 buf_ptr(&ptr_type->name))); 13676 return ira->codegen->invalid_instruction; 13677 } 13678 // this dereference is always an rvalue because in the IR gen we identify lvalue and emit 13679 // one of the ptr instructions 13680 IrInstruction *result = ir_get_deref(ira, &instruction->base, ptr); 13681 if (result == ira->codegen->invalid_instruction) 13682 return ira->codegen->invalid_instruction; 13683 return result; 13684 } 13685 case IrUnOpOptional: 13686 return ir_analyze_maybe(ira, instruction); 13687 } 13688 zig_unreachable(); 13689 } 13690 13691 static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) { 13692 IrBasicBlock *old_dest_block = br_instruction->dest_block; 13693 13694 bool is_comptime; 13695 if (!ir_resolve_comptime(ira, br_instruction->is_comptime->child, &is_comptime)) 13696 return ir_unreach_error(ira); 13697 13698 if (is_comptime || old_dest_block->ref_count == 1) 13699 return ir_inline_bb(ira, &br_instruction->base, old_dest_block); 13700 13701 IrBasicBlock *new_bb = ir_get_new_bb_runtime(ira, old_dest_block, &br_instruction->base); 13702 if (new_bb == nullptr) 13703 return ir_unreach_error(ira); 13704 13705 IrInstruction *result = ir_build_br(&ira->new_irb, 13706 br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr); 13707 result->value.type = ira->codegen->builtin_types.entry_unreachable; 13708 return ir_finish_anal(ira, result); 13709 } 13710 13711 static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructionCondBr *cond_br_instruction) { 13712 IrInstruction *condition = cond_br_instruction->condition->child; 13713 if (type_is_invalid(condition->value.type)) 13714 return ir_unreach_error(ira); 13715 13716 bool is_comptime; 13717 if (!ir_resolve_comptime(ira, cond_br_instruction->is_comptime->child, &is_comptime)) 13718 return ir_unreach_error(ira); 13719 13720 if (is_comptime || instr_is_comptime(condition)) { 13721 bool cond_is_true; 13722 if (!ir_resolve_bool(ira, condition, &cond_is_true)) 13723 return ir_unreach_error(ira); 13724 13725 IrBasicBlock *old_dest_block = cond_is_true ? 13726 cond_br_instruction->then_block : cond_br_instruction->else_block; 13727 13728 if (is_comptime || old_dest_block->ref_count == 1) 13729 return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block); 13730 13731 IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base); 13732 if (new_dest_block == nullptr) 13733 return ir_unreach_error(ira); 13734 13735 IrInstruction *result = ir_build_br(&ira->new_irb, 13736 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr); 13737 result->value.type = ira->codegen->builtin_types.entry_unreachable; 13738 return ir_finish_anal(ira, result); 13739 } 13740 13741 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 13742 IrInstruction *casted_condition = ir_implicit_cast(ira, condition, bool_type); 13743 if (casted_condition == ira->codegen->invalid_instruction) 13744 return ir_unreach_error(ira); 13745 13746 assert(cond_br_instruction->then_block != cond_br_instruction->else_block); 13747 IrBasicBlock *new_then_block = ir_get_new_bb_runtime(ira, cond_br_instruction->then_block, &cond_br_instruction->base); 13748 if (new_then_block == nullptr) 13749 return ir_unreach_error(ira); 13750 13751 IrBasicBlock *new_else_block = ir_get_new_bb_runtime(ira, cond_br_instruction->else_block, &cond_br_instruction->base); 13752 if (new_else_block == nullptr) 13753 return ir_unreach_error(ira); 13754 13755 IrInstruction *result = ir_build_cond_br(&ira->new_irb, 13756 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, 13757 casted_condition, new_then_block, new_else_block, nullptr); 13758 result->value.type = ira->codegen->builtin_types.entry_unreachable; 13759 return ir_finish_anal(ira, result); 13760 } 13761 13762 static IrInstruction *ir_analyze_instruction_unreachable(IrAnalyze *ira, 13763 IrInstructionUnreachable *unreachable_instruction) 13764 { 13765 IrInstruction *result = ir_build_unreachable(&ira->new_irb, 13766 unreachable_instruction->base.scope, unreachable_instruction->base.source_node); 13767 result->value.type = ira->codegen->builtin_types.entry_unreachable; 13768 return ir_finish_anal(ira, result); 13769 } 13770 13771 static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPhi *phi_instruction) { 13772 if (ira->const_predecessor_bb) { 13773 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 13774 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; 13775 if (predecessor != ira->const_predecessor_bb) 13776 continue; 13777 IrInstruction *value = phi_instruction->incoming_values[i]->child; 13778 assert(value->value.type); 13779 if (type_is_invalid(value->value.type)) 13780 return ira->codegen->invalid_instruction; 13781 13782 if (value->value.special != ConstValSpecialRuntime) { 13783 IrInstruction *result = ir_const(ira, &phi_instruction->base, nullptr); 13784 // TODO use copy_const_val? 13785 result->value = value->value; 13786 return result; 13787 } else { 13788 return value; 13789 } 13790 } 13791 zig_unreachable(); 13792 } 13793 13794 ZigList<IrBasicBlock*> new_incoming_blocks = {0}; 13795 ZigList<IrInstruction*> new_incoming_values = {0}; 13796 13797 for (size_t i = 0; i < phi_instruction->incoming_count; i += 1) { 13798 IrBasicBlock *predecessor = phi_instruction->incoming_blocks[i]; 13799 if (predecessor->ref_count == 0) 13800 continue; 13801 13802 13803 IrInstruction *old_value = phi_instruction->incoming_values[i]; 13804 assert(old_value); 13805 IrInstruction *new_value = old_value->child; 13806 if (!new_value || new_value->value.type->id == ZigTypeIdUnreachable || predecessor->other == nullptr) 13807 continue; 13808 13809 if (type_is_invalid(new_value->value.type)) 13810 return ira->codegen->invalid_instruction; 13811 13812 13813 assert(predecessor->other); 13814 new_incoming_blocks.append(predecessor->other); 13815 new_incoming_values.append(new_value); 13816 } 13817 13818 if (new_incoming_blocks.length == 0) { 13819 IrInstruction *result = ir_build_unreachable(&ira->new_irb, 13820 phi_instruction->base.scope, phi_instruction->base.source_node); 13821 result->value.type = ira->codegen->builtin_types.entry_unreachable; 13822 return ir_finish_anal(ira, result); 13823 } 13824 13825 if (new_incoming_blocks.length == 1) { 13826 return new_incoming_values.at(0); 13827 } 13828 13829 ZigType *resolved_type = ir_resolve_peer_types(ira, phi_instruction->base.source_node, nullptr, 13830 new_incoming_values.items, new_incoming_values.length); 13831 if (type_is_invalid(resolved_type)) 13832 return ira->codegen->invalid_instruction; 13833 13834 if (resolved_type->id == ZigTypeIdComptimeFloat || 13835 resolved_type->id == ZigTypeIdComptimeInt || 13836 resolved_type->id == ZigTypeIdNull || 13837 resolved_type->id == ZigTypeIdUndefined) 13838 { 13839 ir_add_error_node(ira, phi_instruction->base.source_node, 13840 buf_sprintf("unable to infer expression type")); 13841 return ira->codegen->invalid_instruction; 13842 } 13843 13844 bool all_stack_ptrs = (resolved_type->id == ZigTypeIdPointer); 13845 13846 // cast all values to the resolved type. however we can't put cast instructions in front of the phi instruction. 13847 // so we go back and insert the casts as the last instruction in the corresponding predecessor blocks, and 13848 // then make sure the branch instruction is preserved. 13849 IrBasicBlock *cur_bb = ira->new_irb.current_basic_block; 13850 for (size_t i = 0; i < new_incoming_values.length; i += 1) { 13851 IrInstruction *new_value = new_incoming_values.at(i); 13852 IrBasicBlock *predecessor = new_incoming_blocks.at(i); 13853 IrInstruction *branch_instruction = predecessor->instruction_list.pop(); 13854 ir_set_cursor_at_end(&ira->new_irb, predecessor); 13855 IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); 13856 if (casted_value == ira->codegen->invalid_instruction) { 13857 return ira->codegen->invalid_instruction; 13858 } 13859 new_incoming_values.items[i] = casted_value; 13860 predecessor->instruction_list.append(branch_instruction); 13861 13862 if (all_stack_ptrs && (casted_value->value.special != ConstValSpecialRuntime || 13863 casted_value->value.data.rh_ptr != RuntimeHintPtrStack)) 13864 { 13865 all_stack_ptrs = false; 13866 } 13867 } 13868 ir_set_cursor_at_end(&ira->new_irb, cur_bb); 13869 13870 IrInstruction *result = ir_build_phi(&ira->new_irb, 13871 phi_instruction->base.scope, phi_instruction->base.source_node, 13872 new_incoming_blocks.length, new_incoming_blocks.items, new_incoming_values.items); 13873 result->value.type = resolved_type; 13874 13875 if (all_stack_ptrs) { 13876 assert(result->value.special == ConstValSpecialRuntime); 13877 result->value.data.rh_ptr = RuntimeHintPtrStack; 13878 } 13879 13880 return result; 13881 } 13882 13883 static IrInstruction *ir_analyze_instruction_var_ptr(IrAnalyze *ira, IrInstructionVarPtr *instruction) { 13884 ZigVar *var = instruction->var; 13885 IrInstruction *result = ir_get_var_ptr(ira, &instruction->base, var); 13886 if (instruction->crossed_fndef_scope != nullptr && !instr_is_comptime(result)) { 13887 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 13888 buf_sprintf("'%s' not accessible from inner function", buf_ptr(&var->name))); 13889 add_error_note(ira->codegen, msg, instruction->crossed_fndef_scope->base.source_node, 13890 buf_sprintf("crossed function definition here")); 13891 add_error_note(ira->codegen, msg, var->decl_node, 13892 buf_sprintf("declared here")); 13893 return ira->codegen->invalid_instruction; 13894 } 13895 return result; 13896 } 13897 13898 static ZigType *adjust_ptr_align(CodeGen *g, ZigType *ptr_type, uint32_t new_align) { 13899 assert(ptr_type->id == ZigTypeIdPointer); 13900 return get_pointer_to_type_extra(g, 13901 ptr_type->data.pointer.child_type, 13902 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 13903 ptr_type->data.pointer.ptr_len, 13904 new_align, 13905 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes); 13906 } 13907 13908 static ZigType *adjust_slice_align(CodeGen *g, ZigType *slice_type, uint32_t new_align) { 13909 assert(is_slice(slice_type)); 13910 ZigType *ptr_type = adjust_ptr_align(g, slice_type->data.structure.fields[slice_ptr_index].type_entry, 13911 new_align); 13912 return get_slice_type(g, ptr_type); 13913 } 13914 13915 static ZigType *adjust_ptr_len(CodeGen *g, ZigType *ptr_type, PtrLen ptr_len) { 13916 assert(ptr_type->id == ZigTypeIdPointer); 13917 return get_pointer_to_type_extra(g, 13918 ptr_type->data.pointer.child_type, 13919 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 13920 ptr_len, 13921 ptr_type->data.pointer.explicit_alignment, 13922 ptr_type->data.pointer.bit_offset_in_host, ptr_type->data.pointer.host_int_bytes); 13923 } 13924 13925 static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstructionElemPtr *elem_ptr_instruction) { 13926 Error err; 13927 IrInstruction *array_ptr = elem_ptr_instruction->array_ptr->child; 13928 if (type_is_invalid(array_ptr->value.type)) 13929 return ira->codegen->invalid_instruction; 13930 13931 ConstExprValue *orig_array_ptr_val = &array_ptr->value; 13932 13933 IrInstruction *elem_index = elem_ptr_instruction->elem_index->child; 13934 if (type_is_invalid(elem_index->value.type)) 13935 return ira->codegen->invalid_instruction; 13936 13937 ZigType *ptr_type = orig_array_ptr_val->type; 13938 assert(ptr_type->id == ZigTypeIdPointer); 13939 13940 ZigType *array_type = ptr_type->data.pointer.child_type; 13941 13942 // At first return_type will be the pointer type we want to return, except with an optimistic alignment. 13943 // We will adjust return_type's alignment before returning it. 13944 ZigType *return_type; 13945 13946 if (type_is_invalid(array_type)) { 13947 return ira->codegen->invalid_instruction; 13948 } else if (array_type->id == ZigTypeIdArray || 13949 (array_type->id == ZigTypeIdPointer && 13950 array_type->data.pointer.ptr_len == PtrLenSingle && 13951 array_type->data.pointer.child_type->id == ZigTypeIdArray)) 13952 { 13953 if (array_type->id == ZigTypeIdPointer) { 13954 array_type = array_type->data.pointer.child_type; 13955 ptr_type = ptr_type->data.pointer.child_type; 13956 if (orig_array_ptr_val->special != ConstValSpecialRuntime) { 13957 orig_array_ptr_val = ir_const_ptr_pointee(ira, orig_array_ptr_val, 13958 elem_ptr_instruction->base.source_node); 13959 if (orig_array_ptr_val == nullptr) 13960 return ira->codegen->invalid_instruction; 13961 } 13962 } 13963 if (array_type->data.array.len == 0) { 13964 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 13965 buf_sprintf("index 0 outside array of size 0")); 13966 return ira->codegen->invalid_instruction; 13967 } 13968 ZigType *child_type = array_type->data.array.child_type; 13969 if (ptr_type->data.pointer.host_int_bytes == 0) { 13970 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 13971 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 13972 elem_ptr_instruction->ptr_len, 13973 ptr_type->data.pointer.explicit_alignment, 0, 0); 13974 } else { 13975 uint64_t elem_val_scalar; 13976 if (!ir_resolve_usize(ira, elem_index, &elem_val_scalar)) 13977 return ira->codegen->invalid_instruction; 13978 13979 size_t bit_width = type_size_bits(ira->codegen, child_type); 13980 size_t bit_offset = bit_width * elem_val_scalar; 13981 13982 return_type = get_pointer_to_type_extra(ira->codegen, child_type, 13983 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 13984 elem_ptr_instruction->ptr_len, 13985 1, (uint32_t)bit_offset, ptr_type->data.pointer.host_int_bytes); 13986 } 13987 } else if (array_type->id == ZigTypeIdPointer) { 13988 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 13989 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 13990 buf_sprintf("index of single-item pointer")); 13991 return ira->codegen->invalid_instruction; 13992 } 13993 return_type = adjust_ptr_len(ira->codegen, array_type, elem_ptr_instruction->ptr_len); 13994 } else if (is_slice(array_type)) { 13995 return_type = adjust_ptr_len(ira->codegen, array_type->data.structure.fields[slice_ptr_index].type_entry, 13996 elem_ptr_instruction->ptr_len); 13997 } else if (array_type->id == ZigTypeIdArgTuple) { 13998 ConstExprValue *ptr_val = ir_resolve_const(ira, array_ptr, UndefBad); 13999 if (!ptr_val) 14000 return ira->codegen->invalid_instruction; 14001 ConstExprValue *args_val = ir_const_ptr_pointee(ira, ptr_val, elem_ptr_instruction->base.source_node); 14002 if (args_val == nullptr) 14003 return ira->codegen->invalid_instruction; 14004 size_t start = args_val->data.x_arg_tuple.start_index; 14005 size_t end = args_val->data.x_arg_tuple.end_index; 14006 uint64_t elem_index_val; 14007 if (!ir_resolve_usize(ira, elem_index, &elem_index_val)) 14008 return ira->codegen->invalid_instruction; 14009 size_t index = elem_index_val; 14010 size_t len = end - start; 14011 if (index >= len) { 14012 ir_add_error(ira, &elem_ptr_instruction->base, 14013 buf_sprintf("index %" ZIG_PRI_usize " outside argument list of size %" ZIG_PRI_usize "", index, len)); 14014 return ira->codegen->invalid_instruction; 14015 } 14016 size_t abs_index = start + index; 14017 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 14018 assert(fn_entry); 14019 ZigVar *var = get_fn_var_by_index(fn_entry, abs_index); 14020 bool is_const = true; 14021 bool is_volatile = false; 14022 if (var) { 14023 return ir_get_var_ptr(ira, &elem_ptr_instruction->base, var); 14024 } else { 14025 return ir_get_const_ptr(ira, &elem_ptr_instruction->base, &ira->codegen->const_void_val, 14026 ira->codegen->builtin_types.entry_void, ConstPtrMutComptimeConst, is_const, is_volatile, 0); 14027 } 14028 } else { 14029 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 14030 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name))); 14031 return ira->codegen->invalid_instruction; 14032 } 14033 14034 ZigType *usize = ira->codegen->builtin_types.entry_usize; 14035 IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize); 14036 if (casted_elem_index == ira->codegen->invalid_instruction) 14037 return ira->codegen->invalid_instruction; 14038 14039 bool safety_check_on = elem_ptr_instruction->safety_check_on; 14040 if ((err = ensure_complete_type(ira->codegen, return_type->data.pointer.child_type))) 14041 return ira->codegen->invalid_instruction; 14042 14043 uint64_t elem_size = type_size(ira->codegen, return_type->data.pointer.child_type); 14044 uint64_t abi_align = get_abi_alignment(ira->codegen, return_type->data.pointer.child_type); 14045 uint64_t ptr_align = get_ptr_align(ira->codegen, return_type); 14046 if (instr_is_comptime(casted_elem_index)) { 14047 uint64_t index = bigint_as_unsigned(&casted_elem_index->value.data.x_bigint); 14048 if (array_type->id == ZigTypeIdArray) { 14049 uint64_t array_len = array_type->data.array.len; 14050 if (index >= array_len) { 14051 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 14052 buf_sprintf("index %" ZIG_PRI_u64 " outside array of size %" ZIG_PRI_u64, 14053 index, array_len)); 14054 return ira->codegen->invalid_instruction; 14055 } 14056 safety_check_on = false; 14057 } 14058 14059 { 14060 // figure out the largest alignment possible 14061 uint64_t chosen_align = abi_align; 14062 if (ptr_align >= abi_align) { 14063 while (ptr_align > abi_align) { 14064 if ((index * elem_size) % ptr_align == 0) { 14065 chosen_align = ptr_align; 14066 break; 14067 } 14068 ptr_align >>= 1; 14069 } 14070 } else if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 14071 chosen_align = ptr_align; 14072 } else { 14073 // can't get here because guaranteed elem_size >= abi_align 14074 zig_unreachable(); 14075 } 14076 return_type = adjust_ptr_align(ira->codegen, return_type, chosen_align); 14077 } 14078 14079 if (orig_array_ptr_val->special != ConstValSpecialRuntime && 14080 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || 14081 array_type->id == ZigTypeIdArray)) 14082 { 14083 ConstExprValue *array_ptr_val = ir_const_ptr_pointee(ira, orig_array_ptr_val, 14084 elem_ptr_instruction->base.source_node); 14085 if (array_ptr_val == nullptr) 14086 return ira->codegen->invalid_instruction; 14087 14088 if (array_ptr_val->special != ConstValSpecialRuntime && 14089 (array_type->id != ZigTypeIdPointer || 14090 array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr)) 14091 { 14092 if (array_type->id == ZigTypeIdPointer) { 14093 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); 14094 ConstExprValue *out_val = &result->value; 14095 out_val->data.x_ptr.mut = array_ptr_val->data.x_ptr.mut; 14096 size_t new_index; 14097 size_t mem_size; 14098 size_t old_size; 14099 switch (array_ptr_val->data.x_ptr.special) { 14100 case ConstPtrSpecialInvalid: 14101 case ConstPtrSpecialDiscard: 14102 zig_unreachable(); 14103 case ConstPtrSpecialRef: 14104 mem_size = 1; 14105 old_size = 1; 14106 new_index = index; 14107 14108 out_val->data.x_ptr.special = ConstPtrSpecialRef; 14109 out_val->data.x_ptr.data.ref.pointee = array_ptr_val->data.x_ptr.data.ref.pointee; 14110 break; 14111 case ConstPtrSpecialBaseArray: 14112 { 14113 size_t offset = array_ptr_val->data.x_ptr.data.base_array.elem_index; 14114 new_index = offset + index; 14115 mem_size = array_ptr_val->data.x_ptr.data.base_array.array_val->type->data.array.len; 14116 old_size = mem_size - offset; 14117 14118 assert(array_ptr_val->data.x_ptr.data.base_array.array_val); 14119 14120 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 14121 out_val->data.x_ptr.data.base_array.array_val = 14122 array_ptr_val->data.x_ptr.data.base_array.array_val; 14123 out_val->data.x_ptr.data.base_array.elem_index = new_index; 14124 out_val->data.x_ptr.data.base_array.is_cstr = 14125 array_ptr_val->data.x_ptr.data.base_array.is_cstr; 14126 14127 break; 14128 } 14129 case ConstPtrSpecialBaseStruct: 14130 zig_panic("TODO elem ptr on a const inner struct"); 14131 case ConstPtrSpecialHardCodedAddr: 14132 zig_unreachable(); 14133 case ConstPtrSpecialFunction: 14134 zig_panic("TODO element ptr of a function casted to a ptr"); 14135 } 14136 if (new_index >= mem_size) { 14137 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 14138 buf_sprintf("index %" ZIG_PRI_u64 " outside pointer of size %" ZIG_PRI_usize "", index, old_size)); 14139 return ira->codegen->invalid_instruction; 14140 } 14141 return result; 14142 } else if (is_slice(array_type)) { 14143 ConstExprValue *ptr_field = &array_ptr_val->data.x_struct.fields[slice_ptr_index]; 14144 if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 14145 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, 14146 array_ptr, casted_elem_index, false, elem_ptr_instruction->ptr_len); 14147 result->value.type = return_type; 14148 return result; 14149 } 14150 ConstExprValue *len_field = &array_ptr_val->data.x_struct.fields[slice_len_index]; 14151 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); 14152 ConstExprValue *out_val = &result->value; 14153 uint64_t slice_len = bigint_as_unsigned(&len_field->data.x_bigint); 14154 if (index >= slice_len) { 14155 ir_add_error_node(ira, elem_ptr_instruction->base.source_node, 14156 buf_sprintf("index %" ZIG_PRI_u64 " outside slice of size %" ZIG_PRI_u64, 14157 index, slice_len)); 14158 return ira->codegen->invalid_instruction; 14159 } 14160 out_val->data.x_ptr.mut = ptr_field->data.x_ptr.mut; 14161 switch (ptr_field->data.x_ptr.special) { 14162 case ConstPtrSpecialInvalid: 14163 case ConstPtrSpecialDiscard: 14164 zig_unreachable(); 14165 case ConstPtrSpecialRef: 14166 out_val->data.x_ptr.special = ConstPtrSpecialRef; 14167 out_val->data.x_ptr.data.ref.pointee = ptr_field->data.x_ptr.data.ref.pointee; 14168 break; 14169 case ConstPtrSpecialBaseArray: 14170 { 14171 size_t offset = ptr_field->data.x_ptr.data.base_array.elem_index; 14172 uint64_t new_index = offset + index; 14173 assert(new_index < ptr_field->data.x_ptr.data.base_array.array_val->type->data.array.len); 14174 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 14175 out_val->data.x_ptr.data.base_array.array_val = 14176 ptr_field->data.x_ptr.data.base_array.array_val; 14177 out_val->data.x_ptr.data.base_array.elem_index = new_index; 14178 out_val->data.x_ptr.data.base_array.is_cstr = 14179 ptr_field->data.x_ptr.data.base_array.is_cstr; 14180 break; 14181 } 14182 case ConstPtrSpecialBaseStruct: 14183 zig_panic("TODO elem ptr on a slice backed by const inner struct"); 14184 case ConstPtrSpecialHardCodedAddr: 14185 zig_unreachable(); 14186 case ConstPtrSpecialFunction: 14187 zig_panic("TODO elem ptr on a slice that was ptrcast from a function"); 14188 } 14189 return result; 14190 } else if (array_type->id == ZigTypeIdArray) { 14191 IrInstruction *result = ir_const(ira, &elem_ptr_instruction->base, return_type); 14192 ConstExprValue *out_val = &result->value; 14193 out_val->data.x_ptr.special = ConstPtrSpecialBaseArray; 14194 out_val->data.x_ptr.mut = orig_array_ptr_val->data.x_ptr.mut; 14195 out_val->data.x_ptr.data.base_array.array_val = array_ptr_val; 14196 out_val->data.x_ptr.data.base_array.elem_index = index; 14197 return result; 14198 } else { 14199 zig_unreachable(); 14200 } 14201 } 14202 } 14203 14204 } else { 14205 // runtime known element index 14206 if (type_requires_comptime(return_type)) { 14207 ir_add_error(ira, elem_index, 14208 buf_sprintf("values of type '%s' must be comptime known, but index value is runtime known", 14209 buf_ptr(&return_type->data.pointer.child_type->name))); 14210 return ira->codegen->invalid_instruction; 14211 } 14212 if (ptr_align < abi_align) { 14213 if (elem_size >= ptr_align && elem_size % ptr_align == 0) { 14214 return_type = adjust_ptr_align(ira->codegen, return_type, ptr_align); 14215 } else { 14216 // can't get here because guaranteed elem_size >= abi_align 14217 zig_unreachable(); 14218 } 14219 } else { 14220 return_type = adjust_ptr_align(ira->codegen, return_type, abi_align); 14221 } 14222 } 14223 14224 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, 14225 array_ptr, casted_elem_index, safety_check_on, elem_ptr_instruction->ptr_len); 14226 result->value.type = return_type; 14227 return result; 14228 } 14229 14230 static IrInstruction *ir_analyze_container_member_access_inner(IrAnalyze *ira, 14231 ZigType *bare_struct_type, Buf *field_name, IrInstruction *source_instr, 14232 IrInstruction *container_ptr, ZigType *container_type) 14233 { 14234 if (!is_slice(bare_struct_type)) { 14235 ScopeDecls *container_scope = get_container_scope(bare_struct_type); 14236 assert(container_scope != nullptr); 14237 auto entry = container_scope->decl_table.maybe_get(field_name); 14238 Tld *tld = entry ? entry->value : nullptr; 14239 if (tld && tld->id == TldIdFn) { 14240 resolve_top_level_decl(ira->codegen, tld, false, source_instr->source_node); 14241 if (tld->resolution == TldResolutionInvalid) 14242 return ira->codegen->invalid_instruction; 14243 TldFn *tld_fn = (TldFn *)tld; 14244 ZigFn *fn_entry = tld_fn->fn_entry; 14245 if (type_is_invalid(fn_entry->type_entry)) 14246 return ira->codegen->invalid_instruction; 14247 14248 IrInstruction *bound_fn_value = ir_build_const_bound_fn(&ira->new_irb, source_instr->scope, 14249 source_instr->source_node, fn_entry, container_ptr); 14250 return ir_get_ref(ira, source_instr, bound_fn_value, true, false); 14251 } 14252 } 14253 const char *prefix_name; 14254 if (is_slice(bare_struct_type)) { 14255 prefix_name = ""; 14256 } else if (bare_struct_type->id == ZigTypeIdStruct) { 14257 prefix_name = "struct "; 14258 } else if (bare_struct_type->id == ZigTypeIdEnum) { 14259 prefix_name = "enum "; 14260 } else if (bare_struct_type->id == ZigTypeIdUnion) { 14261 prefix_name = "union "; 14262 } else { 14263 prefix_name = ""; 14264 } 14265 ir_add_error_node(ira, source_instr->source_node, 14266 buf_sprintf("no member named '%s' in %s'%s'", buf_ptr(field_name), prefix_name, buf_ptr(&bare_struct_type->name))); 14267 return ira->codegen->invalid_instruction; 14268 } 14269 14270 static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_name, 14271 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type) 14272 { 14273 Error err; 14274 14275 ZigType *bare_type = container_ref_type(container_type); 14276 if ((err = ensure_complete_type(ira->codegen, bare_type))) 14277 return ira->codegen->invalid_instruction; 14278 14279 assert(container_ptr->value.type->id == ZigTypeIdPointer); 14280 bool is_const = container_ptr->value.type->data.pointer.is_const; 14281 bool is_volatile = container_ptr->value.type->data.pointer.is_volatile; 14282 if (bare_type->id == ZigTypeIdStruct) { 14283 TypeStructField *field = find_struct_type_field(bare_type, field_name); 14284 if (field) { 14285 bool is_packed = (bare_type->data.structure.layout == ContainerLayoutPacked); 14286 uint32_t align_bytes = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 14287 uint32_t ptr_bit_offset = container_ptr->value.type->data.pointer.bit_offset_in_host; 14288 uint32_t ptr_host_int_bytes = container_ptr->value.type->data.pointer.host_int_bytes; 14289 uint32_t host_int_bytes_for_result_type = (ptr_host_int_bytes == 0) ? 14290 get_host_int_bytes(ira->codegen, bare_type, field) : ptr_host_int_bytes; 14291 if (instr_is_comptime(container_ptr)) { 14292 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 14293 if (!ptr_val) 14294 return ira->codegen->invalid_instruction; 14295 14296 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 14297 ConstExprValue *struct_val = ir_const_ptr_pointee(ira, ptr_val, source_instr->source_node); 14298 if (struct_val == nullptr) 14299 return ira->codegen->invalid_instruction; 14300 if (type_is_invalid(struct_val->type)) 14301 return ira->codegen->invalid_instruction; 14302 ConstExprValue *field_val = &struct_val->data.x_struct.fields[field->src_index]; 14303 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_val->type, 14304 is_const, is_volatile, PtrLenSingle, align_bytes, 14305 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), 14306 (uint32_t)host_int_bytes_for_result_type); 14307 IrInstruction *result = ir_const(ira, source_instr, ptr_type); 14308 ConstExprValue *const_val = &result->value; 14309 const_val->data.x_ptr.special = ConstPtrSpecialBaseStruct; 14310 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; 14311 const_val->data.x_ptr.data.base_struct.struct_val = struct_val; 14312 const_val->data.x_ptr.data.base_struct.field_index = field->src_index; 14313 return result; 14314 } 14315 } 14316 IrInstruction *result = ir_build_struct_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, 14317 container_ptr, field); 14318 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, 14319 PtrLenSingle, 14320 align_bytes, 14321 (uint32_t)(ptr_bit_offset + field->bit_offset_in_host), 14322 host_int_bytes_for_result_type); 14323 return result; 14324 } else { 14325 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 14326 source_instr, container_ptr, container_type); 14327 } 14328 } else if (bare_type->id == ZigTypeIdEnum) { 14329 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 14330 source_instr, container_ptr, container_type); 14331 } else if (bare_type->id == ZigTypeIdUnion) { 14332 TypeUnionField *field = find_union_type_field(bare_type, field_name); 14333 if (field) { 14334 if (instr_is_comptime(container_ptr)) { 14335 ConstExprValue *ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 14336 if (!ptr_val) 14337 return ira->codegen->invalid_instruction; 14338 14339 if (ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 14340 ConstExprValue *union_val = ir_const_ptr_pointee(ira, ptr_val, source_instr->source_node); 14341 if (union_val == nullptr) 14342 return ira->codegen->invalid_instruction; 14343 if (type_is_invalid(union_val->type)) 14344 return ira->codegen->invalid_instruction; 14345 14346 TypeUnionField *actual_field = find_union_field_by_tag(bare_type, &union_val->data.x_union.tag); 14347 if (actual_field == nullptr) 14348 zig_unreachable(); 14349 14350 if (field != actual_field) { 14351 ir_add_error_node(ira, source_instr->source_node, 14352 buf_sprintf("accessing union field '%s' while field '%s' is set", buf_ptr(field_name), 14353 buf_ptr(actual_field->name))); 14354 return ira->codegen->invalid_instruction; 14355 } 14356 14357 ConstExprValue *payload_val = union_val->data.x_union.payload; 14358 14359 ZigType *field_type = field->type_entry; 14360 if (field_type->id == ZigTypeIdVoid) { 14361 assert(payload_val == nullptr); 14362 payload_val = create_const_vals(1); 14363 payload_val->special = ConstValSpecialStatic; 14364 payload_val->type = field_type; 14365 } 14366 14367 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, field_type, 14368 is_const, is_volatile, PtrLenSingle, 0, 0, 0); 14369 14370 IrInstruction *result = ir_const(ira, source_instr, ptr_type); 14371 ConstExprValue *const_val = &result->value; 14372 const_val->data.x_ptr.special = ConstPtrSpecialRef; 14373 const_val->data.x_ptr.mut = container_ptr->value.data.x_ptr.mut; 14374 const_val->data.x_ptr.data.ref.pointee = payload_val; 14375 return result; 14376 } 14377 } 14378 14379 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, source_instr->scope, source_instr->source_node, container_ptr, field); 14380 result->value.type = get_pointer_to_type_extra(ira->codegen, field->type_entry, is_const, is_volatile, 14381 PtrLenSingle, 0, 0, 0); 14382 return result; 14383 } else { 14384 return ir_analyze_container_member_access_inner(ira, bare_type, field_name, 14385 source_instr, container_ptr, container_type); 14386 } 14387 } else { 14388 zig_unreachable(); 14389 } 14390 } 14391 14392 static void add_link_lib_symbol(IrAnalyze *ira, Buf *lib_name, Buf *symbol_name, AstNode *source_node) { 14393 LinkLib *link_lib = add_link_lib(ira->codegen, lib_name); 14394 for (size_t i = 0; i < link_lib->symbols.length; i += 1) { 14395 Buf *existing_symbol_name = link_lib->symbols.at(i); 14396 if (buf_eql_buf(existing_symbol_name, symbol_name)) { 14397 return; 14398 } 14399 } 14400 for (size_t i = 0; i < ira->codegen->forbidden_libs.length; i += 1) { 14401 Buf *forbidden_lib_name = ira->codegen->forbidden_libs.at(i); 14402 if (buf_eql_buf(lib_name, forbidden_lib_name)) { 14403 ir_add_error_node(ira, source_node, 14404 buf_sprintf("linking against forbidden library '%s'", buf_ptr(symbol_name))); 14405 } 14406 } 14407 link_lib->symbols.append(symbol_name); 14408 } 14409 14410 14411 static IrInstruction *ir_analyze_decl_ref(IrAnalyze *ira, IrInstruction *source_instruction, Tld *tld) { 14412 bool pointer_only = false; 14413 resolve_top_level_decl(ira->codegen, tld, pointer_only, source_instruction->source_node); 14414 if (tld->resolution == TldResolutionInvalid) 14415 return ira->codegen->invalid_instruction; 14416 14417 switch (tld->id) { 14418 case TldIdContainer: 14419 case TldIdCompTime: 14420 zig_unreachable(); 14421 case TldIdVar: 14422 { 14423 TldVar *tld_var = (TldVar *)tld; 14424 ZigVar *var = tld_var->var; 14425 if (tld_var->extern_lib_name != nullptr) { 14426 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, source_instruction->source_node); 14427 } 14428 14429 return ir_get_var_ptr(ira, source_instruction, var); 14430 } 14431 case TldIdFn: 14432 { 14433 TldFn *tld_fn = (TldFn *)tld; 14434 ZigFn *fn_entry = tld_fn->fn_entry; 14435 assert(fn_entry->type_entry); 14436 14437 if (type_is_invalid(fn_entry->type_entry)) 14438 return ira->codegen->invalid_instruction; 14439 14440 // TODO instead of allocating this every time, put it in the tld value and we can reference 14441 // the same one every time 14442 ConstExprValue *const_val = create_const_vals(1); 14443 const_val->special = ConstValSpecialStatic; 14444 const_val->type = fn_entry->type_entry; 14445 const_val->data.x_ptr.data.fn.fn_entry = fn_entry; 14446 const_val->data.x_ptr.special = ConstPtrSpecialFunction; 14447 const_val->data.x_ptr.mut = ConstPtrMutComptimeConst; 14448 14449 if (tld_fn->extern_lib_name != nullptr) { 14450 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, source_instruction->source_node); 14451 } 14452 14453 bool ptr_is_const = true; 14454 bool ptr_is_volatile = false; 14455 return ir_get_const_ptr(ira, source_instruction, const_val, fn_entry->type_entry, 14456 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14457 } 14458 } 14459 zig_unreachable(); 14460 } 14461 14462 static ErrorTableEntry *find_err_table_entry(ZigType *err_set_type, Buf *field_name) { 14463 assert(err_set_type->id == ZigTypeIdErrorSet); 14464 for (uint32_t i = 0; i < err_set_type->data.error_set.err_count; i += 1) { 14465 ErrorTableEntry *err_table_entry = err_set_type->data.error_set.errors[i]; 14466 if (buf_eql_buf(&err_table_entry->name, field_name)) { 14467 return err_table_entry; 14468 } 14469 } 14470 return nullptr; 14471 } 14472 14473 static IrInstruction *ir_analyze_instruction_field_ptr(IrAnalyze *ira, IrInstructionFieldPtr *field_ptr_instruction) { 14474 Error err; 14475 IrInstruction *container_ptr = field_ptr_instruction->container_ptr->child; 14476 if (type_is_invalid(container_ptr->value.type)) 14477 return ira->codegen->invalid_instruction; 14478 14479 if (container_ptr->value.type->id != ZigTypeIdPointer) { 14480 ir_add_error_node(ira, field_ptr_instruction->base.source_node, 14481 buf_sprintf("attempt to dereference non-pointer type '%s'", 14482 buf_ptr(&container_ptr->value.type->name))); 14483 return ira->codegen->invalid_instruction; 14484 } 14485 ZigType *container_type = container_ptr->value.type->data.pointer.child_type; 14486 14487 Buf *field_name = field_ptr_instruction->field_name_buffer; 14488 if (!field_name) { 14489 IrInstruction *field_name_expr = field_ptr_instruction->field_name_expr->child; 14490 field_name = ir_resolve_str(ira, field_name_expr); 14491 if (!field_name) 14492 return ira->codegen->invalid_instruction; 14493 } 14494 14495 14496 AstNode *source_node = field_ptr_instruction->base.source_node; 14497 14498 if (type_is_invalid(container_type)) { 14499 return ira->codegen->invalid_instruction; 14500 } else if (is_container_ref(container_type)) { 14501 assert(container_ptr->value.type->id == ZigTypeIdPointer); 14502 if (container_type->id == ZigTypeIdPointer) { 14503 ZigType *bare_type = container_ref_type(container_type); 14504 IrInstruction *container_child = ir_get_deref(ira, &field_ptr_instruction->base, container_ptr); 14505 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_child, bare_type); 14506 return result; 14507 } else { 14508 IrInstruction *result = ir_analyze_container_field_ptr(ira, field_name, &field_ptr_instruction->base, container_ptr, container_type); 14509 return result; 14510 } 14511 } else if (is_array_ref(container_type)) { 14512 if (buf_eql_str(field_name, "len")) { 14513 ConstExprValue *len_val = create_const_vals(1); 14514 if (container_type->id == ZigTypeIdPointer) { 14515 init_const_usize(ira->codegen, len_val, container_type->data.pointer.child_type->data.array.len); 14516 } else { 14517 init_const_usize(ira->codegen, len_val, container_type->data.array.len); 14518 } 14519 14520 ZigType *usize = ira->codegen->builtin_types.entry_usize; 14521 bool ptr_is_const = true; 14522 bool ptr_is_volatile = false; 14523 return ir_get_const_ptr(ira, &field_ptr_instruction->base, len_val, 14524 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14525 } else { 14526 ir_add_error_node(ira, source_node, 14527 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), 14528 buf_ptr(&container_type->name))); 14529 return ira->codegen->invalid_instruction; 14530 } 14531 } else if (container_type->id == ZigTypeIdArgTuple) { 14532 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 14533 if (!container_ptr_val) 14534 return ira->codegen->invalid_instruction; 14535 14536 assert(container_ptr->value.type->id == ZigTypeIdPointer); 14537 ConstExprValue *child_val = ir_const_ptr_pointee(ira, container_ptr_val, source_node); 14538 if (child_val == nullptr) 14539 return ira->codegen->invalid_instruction; 14540 14541 if (buf_eql_str(field_name, "len")) { 14542 ConstExprValue *len_val = create_const_vals(1); 14543 size_t len = child_val->data.x_arg_tuple.end_index - child_val->data.x_arg_tuple.start_index; 14544 init_const_usize(ira->codegen, len_val, len); 14545 14546 ZigType *usize = ira->codegen->builtin_types.entry_usize; 14547 bool ptr_is_const = true; 14548 bool ptr_is_volatile = false; 14549 return ir_get_const_ptr(ira, &field_ptr_instruction->base, len_val, 14550 usize, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14551 } else { 14552 ir_add_error_node(ira, source_node, 14553 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), 14554 buf_ptr(&container_type->name))); 14555 return ira->codegen->invalid_instruction; 14556 } 14557 } else if (container_type->id == ZigTypeIdMetaType) { 14558 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 14559 if (!container_ptr_val) 14560 return ira->codegen->invalid_instruction; 14561 14562 assert(container_ptr->value.type->id == ZigTypeIdPointer); 14563 ConstExprValue *child_val = ir_const_ptr_pointee(ira, container_ptr_val, source_node); 14564 if (child_val == nullptr) 14565 return ira->codegen->invalid_instruction; 14566 ZigType *child_type = child_val->data.x_type; 14567 14568 if (type_is_invalid(child_type)) { 14569 return ira->codegen->invalid_instruction; 14570 } else if (is_container(child_type)) { 14571 if (is_slice(child_type) && buf_eql_str(field_name, "Child")) { 14572 bool ptr_is_const = true; 14573 bool ptr_is_volatile = false; 14574 TypeStructField *ptr_field = &child_type->data.structure.fields[slice_ptr_index]; 14575 assert(ptr_field->type_entry->id == ZigTypeIdPointer); 14576 ZigType *child_type = ptr_field->type_entry->data.pointer.child_type; 14577 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14578 create_const_type(ira->codegen, child_type), 14579 ira->codegen->builtin_types.entry_type, 14580 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14581 } 14582 if (child_type->id == ZigTypeIdEnum) { 14583 if ((err = ensure_complete_type(ira->codegen, child_type))) 14584 return ira->codegen->invalid_instruction; 14585 14586 TypeEnumField *field = find_enum_type_field(child_type, field_name); 14587 if (field) { 14588 bool ptr_is_const = true; 14589 bool ptr_is_volatile = false; 14590 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14591 create_const_enum(child_type, &field->value), child_type, 14592 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14593 } 14594 } 14595 ScopeDecls *container_scope = get_container_scope(child_type); 14596 if (container_scope != nullptr) { 14597 auto entry = container_scope->decl_table.maybe_get(field_name); 14598 Tld *tld = entry ? entry->value : nullptr; 14599 if (tld) { 14600 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld); 14601 } 14602 } 14603 if (child_type->id == ZigTypeIdUnion && 14604 (child_type->data.unionation.decl_node->data.container_decl.init_arg_expr != nullptr || 14605 child_type->data.unionation.decl_node->data.container_decl.auto_enum)) 14606 { 14607 if ((err = ensure_complete_type(ira->codegen, child_type))) 14608 return ira->codegen->invalid_instruction; 14609 TypeUnionField *field = find_union_type_field(child_type, field_name); 14610 if (field) { 14611 ZigType *enum_type = child_type->data.unionation.tag_type; 14612 bool ptr_is_const = true; 14613 bool ptr_is_volatile = false; 14614 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14615 create_const_enum(enum_type, &field->enum_field->value), enum_type, 14616 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14617 } 14618 } 14619 ir_add_error(ira, &field_ptr_instruction->base, 14620 buf_sprintf("container '%s' has no member called '%s'", 14621 buf_ptr(&child_type->name), buf_ptr(field_name))); 14622 return ira->codegen->invalid_instruction; 14623 } else if (child_type->id == ZigTypeIdErrorSet) { 14624 ErrorTableEntry *err_entry; 14625 ZigType *err_set_type; 14626 if (type_is_global_error_set(child_type)) { 14627 auto existing_entry = ira->codegen->error_table.maybe_get(field_name); 14628 if (existing_entry) { 14629 err_entry = existing_entry->value; 14630 } else { 14631 err_entry = allocate<ErrorTableEntry>(1); 14632 err_entry->decl_node = field_ptr_instruction->base.source_node; 14633 buf_init_from_buf(&err_entry->name, field_name); 14634 size_t error_value_count = ira->codegen->errors_by_index.length; 14635 assert((uint32_t)error_value_count < (((uint32_t)1) << (uint32_t)ira->codegen->err_tag_type->data.integral.bit_count)); 14636 err_entry->value = error_value_count; 14637 ira->codegen->errors_by_index.append(err_entry); 14638 ira->codegen->err_enumerators.append(ZigLLVMCreateDebugEnumerator(ira->codegen->dbuilder, 14639 buf_ptr(field_name), error_value_count)); 14640 ira->codegen->error_table.put(field_name, err_entry); 14641 } 14642 if (err_entry->set_with_only_this_in_it == nullptr) { 14643 err_entry->set_with_only_this_in_it = make_err_set_with_one_item(ira->codegen, 14644 field_ptr_instruction->base.scope, field_ptr_instruction->base.source_node, 14645 err_entry); 14646 } 14647 err_set_type = err_entry->set_with_only_this_in_it; 14648 } else { 14649 if (!resolve_inferred_error_set(ira->codegen, child_type, field_ptr_instruction->base.source_node)) { 14650 return ira->codegen->invalid_instruction; 14651 } 14652 err_entry = find_err_table_entry(child_type, field_name); 14653 if (err_entry == nullptr) { 14654 ir_add_error(ira, &field_ptr_instruction->base, 14655 buf_sprintf("no error named '%s' in '%s'", buf_ptr(field_name), buf_ptr(&child_type->name))); 14656 return ira->codegen->invalid_instruction; 14657 } 14658 err_set_type = child_type; 14659 } 14660 ConstExprValue *const_val = create_const_vals(1); 14661 const_val->special = ConstValSpecialStatic; 14662 const_val->type = err_set_type; 14663 const_val->data.x_err_set = err_entry; 14664 14665 bool ptr_is_const = true; 14666 bool ptr_is_volatile = false; 14667 return ir_get_const_ptr(ira, &field_ptr_instruction->base, const_val, 14668 err_set_type, ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14669 } else if (child_type->id == ZigTypeIdInt) { 14670 if (buf_eql_str(field_name, "bit_count")) { 14671 bool ptr_is_const = true; 14672 bool ptr_is_volatile = false; 14673 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14674 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 14675 child_type->data.integral.bit_count, false), 14676 ira->codegen->builtin_types.entry_num_lit_int, 14677 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14678 } else if (buf_eql_str(field_name, "is_signed")) { 14679 bool ptr_is_const = true; 14680 bool ptr_is_volatile = false; 14681 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14682 create_const_bool(ira->codegen, child_type->data.integral.is_signed), 14683 ira->codegen->builtin_types.entry_bool, 14684 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14685 } else { 14686 ir_add_error(ira, &field_ptr_instruction->base, 14687 buf_sprintf("type '%s' has no member called '%s'", 14688 buf_ptr(&child_type->name), buf_ptr(field_name))); 14689 return ira->codegen->invalid_instruction; 14690 } 14691 } else if (child_type->id == ZigTypeIdFloat) { 14692 if (buf_eql_str(field_name, "bit_count")) { 14693 bool ptr_is_const = true; 14694 bool ptr_is_volatile = false; 14695 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14696 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 14697 child_type->data.floating.bit_count, false), 14698 ira->codegen->builtin_types.entry_num_lit_int, 14699 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14700 } else { 14701 ir_add_error(ira, &field_ptr_instruction->base, 14702 buf_sprintf("type '%s' has no member called '%s'", 14703 buf_ptr(&child_type->name), buf_ptr(field_name))); 14704 return ira->codegen->invalid_instruction; 14705 } 14706 } else if (child_type->id == ZigTypeIdPointer) { 14707 if (buf_eql_str(field_name, "Child")) { 14708 bool ptr_is_const = true; 14709 bool ptr_is_volatile = false; 14710 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14711 create_const_type(ira->codegen, child_type->data.pointer.child_type), 14712 ira->codegen->builtin_types.entry_type, 14713 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14714 } else if (buf_eql_str(field_name, "alignment")) { 14715 bool ptr_is_const = true; 14716 bool ptr_is_volatile = false; 14717 if ((err = type_resolve(ira->codegen, child_type->data.pointer.child_type, 14718 ResolveStatusAlignmentKnown))) 14719 { 14720 return ira->codegen->invalid_instruction; 14721 } 14722 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14723 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 14724 get_ptr_align(ira->codegen, child_type), false), 14725 ira->codegen->builtin_types.entry_num_lit_int, 14726 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14727 } else { 14728 ir_add_error(ira, &field_ptr_instruction->base, 14729 buf_sprintf("type '%s' has no member called '%s'", 14730 buf_ptr(&child_type->name), buf_ptr(field_name))); 14731 return ira->codegen->invalid_instruction; 14732 } 14733 } else if (child_type->id == ZigTypeIdArray) { 14734 if (buf_eql_str(field_name, "Child")) { 14735 bool ptr_is_const = true; 14736 bool ptr_is_volatile = false; 14737 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14738 create_const_type(ira->codegen, child_type->data.array.child_type), 14739 ira->codegen->builtin_types.entry_type, 14740 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14741 } else if (buf_eql_str(field_name, "len")) { 14742 bool ptr_is_const = true; 14743 bool ptr_is_volatile = false; 14744 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14745 create_const_unsigned_negative(ira->codegen->builtin_types.entry_num_lit_int, 14746 child_type->data.array.len, false), 14747 ira->codegen->builtin_types.entry_num_lit_int, 14748 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14749 } else { 14750 ir_add_error(ira, &field_ptr_instruction->base, 14751 buf_sprintf("type '%s' has no member called '%s'", 14752 buf_ptr(&child_type->name), buf_ptr(field_name))); 14753 return ira->codegen->invalid_instruction; 14754 } 14755 } else if (child_type->id == ZigTypeIdErrorUnion) { 14756 if (buf_eql_str(field_name, "Payload")) { 14757 bool ptr_is_const = true; 14758 bool ptr_is_volatile = false; 14759 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14760 create_const_type(ira->codegen, child_type->data.error_union.payload_type), 14761 ira->codegen->builtin_types.entry_type, 14762 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14763 } else if (buf_eql_str(field_name, "ErrorSet")) { 14764 bool ptr_is_const = true; 14765 bool ptr_is_volatile = false; 14766 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14767 create_const_type(ira->codegen, child_type->data.error_union.err_set_type), 14768 ira->codegen->builtin_types.entry_type, 14769 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14770 } else { 14771 ir_add_error(ira, &field_ptr_instruction->base, 14772 buf_sprintf("type '%s' has no member called '%s'", 14773 buf_ptr(&child_type->name), buf_ptr(field_name))); 14774 return ira->codegen->invalid_instruction; 14775 } 14776 } else if (child_type->id == ZigTypeIdOptional) { 14777 if (buf_eql_str(field_name, "Child")) { 14778 bool ptr_is_const = true; 14779 bool ptr_is_volatile = false; 14780 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14781 create_const_type(ira->codegen, child_type->data.maybe.child_type), 14782 ira->codegen->builtin_types.entry_type, 14783 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14784 } else { 14785 ir_add_error(ira, &field_ptr_instruction->base, 14786 buf_sprintf("type '%s' has no member called '%s'", 14787 buf_ptr(&child_type->name), buf_ptr(field_name))); 14788 return ira->codegen->invalid_instruction; 14789 } 14790 } else if (child_type->id == ZigTypeIdFn) { 14791 if (buf_eql_str(field_name, "ReturnType")) { 14792 if (child_type->data.fn.fn_type_id.return_type == nullptr) { 14793 // Return type can only ever be null, if the function is generic 14794 assert(child_type->data.fn.is_generic); 14795 14796 ir_add_error(ira, &field_ptr_instruction->base, 14797 buf_sprintf("ReturnType has not been resolved because '%s' is generic", buf_ptr(&child_type->name))); 14798 return ira->codegen->invalid_instruction; 14799 } 14800 14801 bool ptr_is_const = true; 14802 bool ptr_is_volatile = false; 14803 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14804 create_const_type(ira->codegen, child_type->data.fn.fn_type_id.return_type), 14805 ira->codegen->builtin_types.entry_type, 14806 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14807 } else if (buf_eql_str(field_name, "is_var_args")) { 14808 bool ptr_is_const = true; 14809 bool ptr_is_volatile = false; 14810 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14811 create_const_bool(ira->codegen, child_type->data.fn.fn_type_id.is_var_args), 14812 ira->codegen->builtin_types.entry_bool, 14813 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14814 } else if (buf_eql_str(field_name, "arg_count")) { 14815 bool ptr_is_const = true; 14816 bool ptr_is_volatile = false; 14817 return ir_get_const_ptr(ira, &field_ptr_instruction->base, 14818 create_const_usize(ira->codegen, child_type->data.fn.fn_type_id.param_count), 14819 ira->codegen->builtin_types.entry_usize, 14820 ConstPtrMutComptimeConst, ptr_is_const, ptr_is_volatile, 0); 14821 } else { 14822 ir_add_error(ira, &field_ptr_instruction->base, 14823 buf_sprintf("type '%s' has no member called '%s'", 14824 buf_ptr(&child_type->name), buf_ptr(field_name))); 14825 return ira->codegen->invalid_instruction; 14826 } 14827 } else { 14828 ir_add_error(ira, &field_ptr_instruction->base, 14829 buf_sprintf("type '%s' does not support field access", buf_ptr(&child_type->name))); 14830 return ira->codegen->invalid_instruction; 14831 } 14832 } else if (container_type->id == ZigTypeIdNamespace) { 14833 assert(container_ptr->value.type->id == ZigTypeIdPointer); 14834 ConstExprValue *container_ptr_val = ir_resolve_const(ira, container_ptr, UndefBad); 14835 if (!container_ptr_val) 14836 return ira->codegen->invalid_instruction; 14837 14838 ConstExprValue *namespace_val = ir_const_ptr_pointee(ira, container_ptr_val, 14839 field_ptr_instruction->base.source_node); 14840 if (namespace_val == nullptr) 14841 return ira->codegen->invalid_instruction; 14842 assert(namespace_val->special == ConstValSpecialStatic); 14843 14844 ImportTableEntry *namespace_import = namespace_val->data.x_import; 14845 14846 Tld *tld = find_decl(ira->codegen, &namespace_import->decls_scope->base, field_name); 14847 if (tld) { 14848 if (tld->visib_mod == VisibModPrivate && 14849 tld->import != source_node->owner) 14850 { 14851 ErrorMsg *msg = ir_add_error_node(ira, source_node, 14852 buf_sprintf("'%s' is private", buf_ptr(field_name))); 14853 add_error_note(ira->codegen, msg, tld->source_node, buf_sprintf("declared here")); 14854 return ira->codegen->invalid_instruction; 14855 } 14856 return ir_analyze_decl_ref(ira, &field_ptr_instruction->base, tld); 14857 } else { 14858 const char *import_name = namespace_import->path ? buf_ptr(namespace_import->path) : "(C import)"; 14859 ir_add_error_node(ira, source_node, 14860 buf_sprintf("no member named '%s' in '%s'", buf_ptr(field_name), import_name)); 14861 return ira->codegen->invalid_instruction; 14862 } 14863 } else { 14864 ir_add_error_node(ira, field_ptr_instruction->base.source_node, 14865 buf_sprintf("type '%s' does not support field access", buf_ptr(&container_type->name))); 14866 return ira->codegen->invalid_instruction; 14867 } 14868 } 14869 14870 static IrInstruction *ir_analyze_instruction_load_ptr(IrAnalyze *ira, IrInstructionLoadPtr *load_ptr_instruction) { 14871 IrInstruction *ptr = load_ptr_instruction->ptr->child; 14872 if (type_is_invalid(ptr->value.type)) 14873 return ira->codegen->invalid_instruction; 14874 return ir_get_deref(ira, &load_ptr_instruction->base, ptr); 14875 } 14876 14877 static IrInstruction *ir_analyze_instruction_store_ptr(IrAnalyze *ira, IrInstructionStorePtr *store_ptr_instruction) { 14878 IrInstruction *ptr = store_ptr_instruction->ptr->child; 14879 if (type_is_invalid(ptr->value.type)) 14880 return ira->codegen->invalid_instruction; 14881 14882 IrInstruction *value = store_ptr_instruction->value->child; 14883 if (type_is_invalid(value->value.type)) 14884 return ira->codegen->invalid_instruction; 14885 14886 if (ptr->value.type->id != ZigTypeIdPointer) { 14887 ir_add_error(ira, ptr, 14888 buf_sprintf("attempt to dereference non pointer type '%s'", buf_ptr(&ptr->value.type->name))); 14889 return ira->codegen->invalid_instruction; 14890 } 14891 14892 if (ptr->value.data.x_ptr.special == ConstPtrSpecialDiscard) { 14893 return ir_const_void(ira, &store_ptr_instruction->base); 14894 } 14895 14896 if (ptr->value.type->data.pointer.is_const && !store_ptr_instruction->base.is_gen) { 14897 ir_add_error(ira, &store_ptr_instruction->base, buf_sprintf("cannot assign to constant")); 14898 return ira->codegen->invalid_instruction; 14899 } 14900 14901 ZigType *child_type = ptr->value.type->data.pointer.child_type; 14902 IrInstruction *casted_value = ir_implicit_cast(ira, value, child_type); 14903 if (casted_value == ira->codegen->invalid_instruction) 14904 return ira->codegen->invalid_instruction; 14905 14906 if (instr_is_comptime(ptr) && ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) { 14907 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst) { 14908 ir_add_error(ira, &store_ptr_instruction->base, buf_sprintf("cannot assign to constant")); 14909 return ira->codegen->invalid_instruction; 14910 } 14911 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) { 14912 if (instr_is_comptime(casted_value)) { 14913 ConstExprValue *dest_val = ir_const_ptr_pointee(ira, &ptr->value, store_ptr_instruction->base.source_node); 14914 if (dest_val == nullptr) 14915 return ira->codegen->invalid_instruction; 14916 if (dest_val->special != ConstValSpecialRuntime) { 14917 *dest_val = casted_value->value; 14918 if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) { 14919 ira->new_irb.current_basic_block->must_be_comptime_source_instr = &store_ptr_instruction->base; 14920 } 14921 return ir_const_void(ira, &store_ptr_instruction->base); 14922 } 14923 } 14924 ir_add_error(ira, &store_ptr_instruction->base, 14925 buf_sprintf("cannot store runtime value in compile time variable")); 14926 ConstExprValue *dest_val = const_ptr_pointee_unchecked(ira->codegen, &ptr->value); 14927 dest_val->type = ira->codegen->builtin_types.entry_invalid; 14928 14929 return ira->codegen->invalid_instruction; 14930 } 14931 } 14932 14933 IrInstruction *result = ir_build_store_ptr(&ira->new_irb, 14934 store_ptr_instruction->base.scope, store_ptr_instruction->base.source_node, 14935 ptr, casted_value); 14936 result->value.type = ira->codegen->builtin_types.entry_void; 14937 return result; 14938 } 14939 14940 static IrInstruction *ir_analyze_instruction_typeof(IrAnalyze *ira, IrInstructionTypeOf *typeof_instruction) { 14941 IrInstruction *expr_value = typeof_instruction->value->child; 14942 ZigType *type_entry = expr_value->value.type; 14943 if (type_is_invalid(type_entry)) 14944 return ira->codegen->invalid_instruction; 14945 switch (type_entry->id) { 14946 case ZigTypeIdInvalid: 14947 zig_unreachable(); // handled above 14948 case ZigTypeIdComptimeFloat: 14949 case ZigTypeIdComptimeInt: 14950 case ZigTypeIdUndefined: 14951 case ZigTypeIdNull: 14952 case ZigTypeIdNamespace: 14953 case ZigTypeIdBoundFn: 14954 case ZigTypeIdMetaType: 14955 case ZigTypeIdVoid: 14956 case ZigTypeIdBool: 14957 case ZigTypeIdUnreachable: 14958 case ZigTypeIdInt: 14959 case ZigTypeIdFloat: 14960 case ZigTypeIdPointer: 14961 case ZigTypeIdArray: 14962 case ZigTypeIdStruct: 14963 case ZigTypeIdOptional: 14964 case ZigTypeIdErrorUnion: 14965 case ZigTypeIdErrorSet: 14966 case ZigTypeIdEnum: 14967 case ZigTypeIdUnion: 14968 case ZigTypeIdFn: 14969 case ZigTypeIdArgTuple: 14970 case ZigTypeIdOpaque: 14971 case ZigTypeIdPromise: 14972 return ir_const_type(ira, &typeof_instruction->base, type_entry); 14973 } 14974 14975 zig_unreachable(); 14976 } 14977 14978 static IrInstruction *ir_analyze_instruction_to_ptr_type(IrAnalyze *ira, 14979 IrInstructionToPtrType *to_ptr_type_instruction) 14980 { 14981 IrInstruction *value = to_ptr_type_instruction->value->child; 14982 ZigType *type_entry = value->value.type; 14983 if (type_is_invalid(type_entry)) 14984 return ira->codegen->invalid_instruction; 14985 14986 ZigType *ptr_type; 14987 if (type_entry->id == ZigTypeIdArray) { 14988 ptr_type = get_pointer_to_type(ira->codegen, type_entry->data.array.child_type, false); 14989 } else if (is_slice(type_entry)) { 14990 ptr_type = adjust_ptr_len(ira->codegen, type_entry->data.structure.fields[0].type_entry, PtrLenSingle); 14991 } else if (type_entry->id == ZigTypeIdArgTuple) { 14992 ConstExprValue *arg_tuple_val = ir_resolve_const(ira, value, UndefBad); 14993 if (!arg_tuple_val) 14994 return ira->codegen->invalid_instruction; 14995 zig_panic("TODO for loop on var args"); 14996 } else { 14997 ir_add_error_node(ira, to_ptr_type_instruction->base.source_node, 14998 buf_sprintf("expected array type, found '%s'", buf_ptr(&type_entry->name))); 14999 return ira->codegen->invalid_instruction; 15000 } 15001 15002 return ir_const_type(ira, &to_ptr_type_instruction->base, ptr_type); 15003 } 15004 15005 static IrInstruction *ir_analyze_instruction_ptr_type_child(IrAnalyze *ira, 15006 IrInstructionPtrTypeChild *ptr_type_child_instruction) 15007 { 15008 IrInstruction *type_value = ptr_type_child_instruction->value->child; 15009 ZigType *type_entry = ir_resolve_type(ira, type_value); 15010 if (type_is_invalid(type_entry)) 15011 return ira->codegen->invalid_instruction; 15012 15013 if (type_entry->id != ZigTypeIdPointer) { 15014 ir_add_error_node(ira, ptr_type_child_instruction->base.source_node, 15015 buf_sprintf("expected pointer type, found '%s'", buf_ptr(&type_entry->name))); 15016 return ira->codegen->invalid_instruction; 15017 } 15018 15019 return ir_const_type(ira, &ptr_type_child_instruction->base, type_entry->data.pointer.child_type); 15020 } 15021 15022 static IrInstruction *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstructionSetCold *instruction) { 15023 if (ira->new_irb.exec->is_inline) { 15024 // ignore setCold when running functions at compile time 15025 return ir_const_void(ira, &instruction->base); 15026 } 15027 15028 IrInstruction *is_cold_value = instruction->is_cold->child; 15029 bool want_cold; 15030 if (!ir_resolve_bool(ira, is_cold_value, &want_cold)) 15031 return ira->codegen->invalid_instruction; 15032 15033 ZigFn *fn_entry = scope_fn_entry(instruction->base.scope); 15034 if (fn_entry == nullptr) { 15035 ir_add_error(ira, &instruction->base, buf_sprintf("@setCold outside function")); 15036 return ira->codegen->invalid_instruction; 15037 } 15038 15039 if (fn_entry->set_cold_node != nullptr) { 15040 ErrorMsg *msg = ir_add_error(ira, &instruction->base, buf_sprintf("cold set twice in same function")); 15041 add_error_note(ira->codegen, msg, fn_entry->set_cold_node, buf_sprintf("first set here")); 15042 return ira->codegen->invalid_instruction; 15043 } 15044 15045 fn_entry->set_cold_node = instruction->base.source_node; 15046 fn_entry->is_cold = want_cold; 15047 15048 return ir_const_void(ira, &instruction->base); 15049 } 15050 15051 static IrInstruction *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira, 15052 IrInstructionSetRuntimeSafety *set_runtime_safety_instruction) 15053 { 15054 if (ira->new_irb.exec->is_inline) { 15055 // ignore setRuntimeSafety when running functions at compile time 15056 return ir_const_void(ira, &set_runtime_safety_instruction->base); 15057 } 15058 15059 bool *safety_off_ptr; 15060 AstNode **safety_set_node_ptr; 15061 15062 Scope *scope = set_runtime_safety_instruction->base.scope; 15063 while (scope != nullptr) { 15064 if (scope->id == ScopeIdBlock) { 15065 ScopeBlock *block_scope = (ScopeBlock *)scope; 15066 safety_off_ptr = &block_scope->safety_off; 15067 safety_set_node_ptr = &block_scope->safety_set_node; 15068 break; 15069 } else if (scope->id == ScopeIdFnDef) { 15070 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 15071 ZigFn *target_fn = def_scope->fn_entry; 15072 assert(target_fn->def_scope != nullptr); 15073 safety_off_ptr = &target_fn->def_scope->safety_off; 15074 safety_set_node_ptr = &target_fn->def_scope->safety_set_node; 15075 break; 15076 } else if (scope->id == ScopeIdDecls) { 15077 ScopeDecls *decls_scope = (ScopeDecls *)scope; 15078 safety_off_ptr = &decls_scope->safety_off; 15079 safety_set_node_ptr = &decls_scope->safety_set_node; 15080 break; 15081 } else { 15082 scope = scope->parent; 15083 continue; 15084 } 15085 } 15086 assert(scope != nullptr); 15087 15088 IrInstruction *safety_on_value = set_runtime_safety_instruction->safety_on->child; 15089 bool want_runtime_safety; 15090 if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety)) 15091 return ira->codegen->invalid_instruction; 15092 15093 AstNode *source_node = set_runtime_safety_instruction->base.source_node; 15094 if (*safety_set_node_ptr) { 15095 ErrorMsg *msg = ir_add_error_node(ira, source_node, 15096 buf_sprintf("runtime safety set twice for same scope")); 15097 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here")); 15098 return ira->codegen->invalid_instruction; 15099 } 15100 *safety_set_node_ptr = source_node; 15101 *safety_off_ptr = !want_runtime_safety; 15102 15103 return ir_const_void(ira, &set_runtime_safety_instruction->base); 15104 } 15105 15106 static IrInstruction *ir_analyze_instruction_set_float_mode(IrAnalyze *ira, 15107 IrInstructionSetFloatMode *instruction) 15108 { 15109 if (ira->new_irb.exec->is_inline) { 15110 // ignore setFloatMode when running functions at compile time 15111 return ir_const_void(ira, &instruction->base); 15112 } 15113 15114 bool *fast_math_on_ptr; 15115 AstNode **fast_math_set_node_ptr; 15116 15117 Scope *scope = instruction->base.scope; 15118 while (scope != nullptr) { 15119 if (scope->id == ScopeIdBlock) { 15120 ScopeBlock *block_scope = (ScopeBlock *)scope; 15121 fast_math_on_ptr = &block_scope->fast_math_on; 15122 fast_math_set_node_ptr = &block_scope->fast_math_set_node; 15123 break; 15124 } else if (scope->id == ScopeIdFnDef) { 15125 ScopeFnDef *def_scope = (ScopeFnDef *)scope; 15126 ZigFn *target_fn = def_scope->fn_entry; 15127 assert(target_fn->def_scope != nullptr); 15128 fast_math_on_ptr = &target_fn->def_scope->fast_math_on; 15129 fast_math_set_node_ptr = &target_fn->def_scope->fast_math_set_node; 15130 break; 15131 } else if (scope->id == ScopeIdDecls) { 15132 ScopeDecls *decls_scope = (ScopeDecls *)scope; 15133 fast_math_on_ptr = &decls_scope->fast_math_on; 15134 fast_math_set_node_ptr = &decls_scope->fast_math_set_node; 15135 break; 15136 } else { 15137 scope = scope->parent; 15138 continue; 15139 } 15140 } 15141 assert(scope != nullptr); 15142 15143 IrInstruction *float_mode_value = instruction->mode_value->child; 15144 FloatMode float_mode_scalar; 15145 if (!ir_resolve_float_mode(ira, float_mode_value, &float_mode_scalar)) 15146 return ira->codegen->invalid_instruction; 15147 15148 AstNode *source_node = instruction->base.source_node; 15149 if (*fast_math_set_node_ptr) { 15150 ErrorMsg *msg = ir_add_error_node(ira, source_node, 15151 buf_sprintf("float mode set twice for same scope")); 15152 add_error_note(ira->codegen, msg, *fast_math_set_node_ptr, buf_sprintf("first set here")); 15153 return ira->codegen->invalid_instruction; 15154 } 15155 *fast_math_set_node_ptr = source_node; 15156 *fast_math_on_ptr = (float_mode_scalar == FloatModeOptimized); 15157 15158 return ir_const_void(ira, &instruction->base); 15159 } 15160 15161 static IrInstruction *ir_analyze_instruction_slice_type(IrAnalyze *ira, 15162 IrInstructionSliceType *slice_type_instruction) 15163 { 15164 Error err; 15165 uint32_t align_bytes = 0; 15166 if (slice_type_instruction->align_value != nullptr) { 15167 if (!ir_resolve_align(ira, slice_type_instruction->align_value->child, &align_bytes)) 15168 return ira->codegen->invalid_instruction; 15169 } 15170 15171 ZigType *child_type = ir_resolve_type(ira, slice_type_instruction->child_type->child); 15172 if (type_is_invalid(child_type)) 15173 return ira->codegen->invalid_instruction; 15174 15175 bool is_const = slice_type_instruction->is_const; 15176 bool is_volatile = slice_type_instruction->is_volatile; 15177 15178 switch (child_type->id) { 15179 case ZigTypeIdInvalid: // handled above 15180 zig_unreachable(); 15181 case ZigTypeIdUnreachable: 15182 case ZigTypeIdUndefined: 15183 case ZigTypeIdNull: 15184 case ZigTypeIdArgTuple: 15185 case ZigTypeIdOpaque: 15186 ir_add_error_node(ira, slice_type_instruction->base.source_node, 15187 buf_sprintf("slice of type '%s' not allowed", buf_ptr(&child_type->name))); 15188 return ira->codegen->invalid_instruction; 15189 case ZigTypeIdMetaType: 15190 case ZigTypeIdVoid: 15191 case ZigTypeIdBool: 15192 case ZigTypeIdInt: 15193 case ZigTypeIdFloat: 15194 case ZigTypeIdPointer: 15195 case ZigTypeIdArray: 15196 case ZigTypeIdStruct: 15197 case ZigTypeIdComptimeFloat: 15198 case ZigTypeIdComptimeInt: 15199 case ZigTypeIdOptional: 15200 case ZigTypeIdErrorUnion: 15201 case ZigTypeIdErrorSet: 15202 case ZigTypeIdEnum: 15203 case ZigTypeIdUnion: 15204 case ZigTypeIdFn: 15205 case ZigTypeIdNamespace: 15206 case ZigTypeIdBoundFn: 15207 case ZigTypeIdPromise: 15208 { 15209 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) 15210 return ira->codegen->invalid_instruction; 15211 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, child_type, 15212 is_const, is_volatile, PtrLenUnknown, align_bytes, 0, 0); 15213 ZigType *result_type = get_slice_type(ira->codegen, slice_ptr_type); 15214 return ir_const_type(ira, &slice_type_instruction->base, result_type); 15215 } 15216 } 15217 zig_unreachable(); 15218 } 15219 15220 static IrInstruction *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAsm *asm_instruction) { 15221 assert(asm_instruction->base.source_node->type == NodeTypeAsmExpr); 15222 15223 AstNodeAsmExpr *asm_expr = &asm_instruction->base.source_node->data.asm_expr; 15224 15225 bool global_scope = (scope_fn_entry(asm_instruction->base.scope) == nullptr); 15226 if (global_scope) { 15227 if (asm_expr->output_list.length != 0 || asm_expr->input_list.length != 0 || 15228 asm_expr->clobber_list.length != 0) 15229 { 15230 ir_add_error(ira, &asm_instruction->base, 15231 buf_sprintf("global assembly cannot have inputs, outputs, or clobbers")); 15232 return ira->codegen->invalid_instruction; 15233 } 15234 15235 buf_append_char(&ira->codegen->global_asm, '\n'); 15236 buf_append_buf(&ira->codegen->global_asm, asm_expr->asm_template); 15237 15238 return ir_const_void(ira, &asm_instruction->base); 15239 } 15240 15241 if (!ir_emit_global_runtime_side_effect(ira, &asm_instruction->base)) 15242 return ira->codegen->invalid_instruction; 15243 15244 // TODO validate the output types and variable types 15245 15246 IrInstruction **input_list = allocate<IrInstruction *>(asm_expr->input_list.length); 15247 IrInstruction **output_types = allocate<IrInstruction *>(asm_expr->output_list.length); 15248 15249 ZigType *return_type = ira->codegen->builtin_types.entry_void; 15250 for (size_t i = 0; i < asm_expr->output_list.length; i += 1) { 15251 AsmOutput *asm_output = asm_expr->output_list.at(i); 15252 if (asm_output->return_type) { 15253 output_types[i] = asm_instruction->output_types[i]->child; 15254 return_type = ir_resolve_type(ira, output_types[i]); 15255 if (type_is_invalid(return_type)) 15256 return ira->codegen->invalid_instruction; 15257 } 15258 } 15259 15260 for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { 15261 input_list[i] = asm_instruction->input_list[i]->child; 15262 if (type_is_invalid(input_list[i]->value.type)) 15263 return ira->codegen->invalid_instruction; 15264 } 15265 15266 IrInstruction *result = ir_build_asm(&ira->new_irb, 15267 asm_instruction->base.scope, asm_instruction->base.source_node, 15268 input_list, output_types, asm_instruction->output_vars, asm_instruction->return_count, 15269 asm_instruction->has_side_effects); 15270 result->value.type = return_type; 15271 return result; 15272 } 15273 15274 static IrInstruction *ir_analyze_instruction_array_type(IrAnalyze *ira, 15275 IrInstructionArrayType *array_type_instruction) 15276 { 15277 Error err; 15278 15279 IrInstruction *size_value = array_type_instruction->size->child; 15280 uint64_t size; 15281 if (!ir_resolve_usize(ira, size_value, &size)) 15282 return ira->codegen->invalid_instruction; 15283 15284 IrInstruction *child_type_value = array_type_instruction->child_type->child; 15285 ZigType *child_type = ir_resolve_type(ira, child_type_value); 15286 if (type_is_invalid(child_type)) 15287 return ira->codegen->invalid_instruction; 15288 switch (child_type->id) { 15289 case ZigTypeIdInvalid: // handled above 15290 zig_unreachable(); 15291 case ZigTypeIdUnreachable: 15292 case ZigTypeIdUndefined: 15293 case ZigTypeIdNull: 15294 case ZigTypeIdArgTuple: 15295 case ZigTypeIdOpaque: 15296 ir_add_error_node(ira, array_type_instruction->base.source_node, 15297 buf_sprintf("array of type '%s' not allowed", buf_ptr(&child_type->name))); 15298 return ira->codegen->invalid_instruction; 15299 case ZigTypeIdMetaType: 15300 case ZigTypeIdVoid: 15301 case ZigTypeIdBool: 15302 case ZigTypeIdInt: 15303 case ZigTypeIdFloat: 15304 case ZigTypeIdPointer: 15305 case ZigTypeIdArray: 15306 case ZigTypeIdStruct: 15307 case ZigTypeIdComptimeFloat: 15308 case ZigTypeIdComptimeInt: 15309 case ZigTypeIdOptional: 15310 case ZigTypeIdErrorUnion: 15311 case ZigTypeIdErrorSet: 15312 case ZigTypeIdEnum: 15313 case ZigTypeIdUnion: 15314 case ZigTypeIdFn: 15315 case ZigTypeIdNamespace: 15316 case ZigTypeIdBoundFn: 15317 case ZigTypeIdPromise: 15318 { 15319 if ((err = ensure_complete_type(ira->codegen, child_type))) 15320 return ira->codegen->invalid_instruction; 15321 ZigType *result_type = get_array_type(ira->codegen, child_type, size); 15322 return ir_const_type(ira, &array_type_instruction->base, result_type); 15323 } 15324 } 15325 zig_unreachable(); 15326 } 15327 15328 static IrInstruction *ir_analyze_instruction_promise_type(IrAnalyze *ira, IrInstructionPromiseType *instruction) { 15329 ZigType *promise_type; 15330 15331 if (instruction->payload_type == nullptr) { 15332 promise_type = ira->codegen->builtin_types.entry_promise; 15333 } else { 15334 ZigType *payload_type = ir_resolve_type(ira, instruction->payload_type->child); 15335 if (type_is_invalid(payload_type)) 15336 return ira->codegen->invalid_instruction; 15337 15338 promise_type = get_promise_type(ira->codegen, payload_type); 15339 } 15340 15341 return ir_const_type(ira, &instruction->base, promise_type); 15342 } 15343 15344 static IrInstruction *ir_analyze_instruction_size_of(IrAnalyze *ira, 15345 IrInstructionSizeOf *size_of_instruction) 15346 { 15347 Error err; 15348 IrInstruction *type_value = size_of_instruction->type_value->child; 15349 ZigType *type_entry = ir_resolve_type(ira, type_value); 15350 15351 if ((err = ensure_complete_type(ira->codegen, type_entry))) 15352 return ira->codegen->invalid_instruction; 15353 15354 switch (type_entry->id) { 15355 case ZigTypeIdInvalid: // handled above 15356 zig_unreachable(); 15357 case ZigTypeIdUnreachable: 15358 case ZigTypeIdUndefined: 15359 case ZigTypeIdNull: 15360 case ZigTypeIdComptimeFloat: 15361 case ZigTypeIdComptimeInt: 15362 case ZigTypeIdBoundFn: 15363 case ZigTypeIdMetaType: 15364 case ZigTypeIdNamespace: 15365 case ZigTypeIdArgTuple: 15366 case ZigTypeIdOpaque: 15367 ir_add_error_node(ira, size_of_instruction->base.source_node, 15368 buf_sprintf("no size available for type '%s'", buf_ptr(&type_entry->name))); 15369 return ira->codegen->invalid_instruction; 15370 case ZigTypeIdVoid: 15371 case ZigTypeIdBool: 15372 case ZigTypeIdInt: 15373 case ZigTypeIdFloat: 15374 case ZigTypeIdPointer: 15375 case ZigTypeIdArray: 15376 case ZigTypeIdStruct: 15377 case ZigTypeIdOptional: 15378 case ZigTypeIdErrorUnion: 15379 case ZigTypeIdErrorSet: 15380 case ZigTypeIdEnum: 15381 case ZigTypeIdUnion: 15382 case ZigTypeIdFn: 15383 case ZigTypeIdPromise: 15384 { 15385 uint64_t size_in_bytes = type_size(ira->codegen, type_entry); 15386 return ir_const_unsigned(ira, &size_of_instruction->base, size_in_bytes); 15387 } 15388 } 15389 zig_unreachable(); 15390 } 15391 15392 static IrInstruction *ir_analyze_instruction_test_non_null(IrAnalyze *ira, IrInstructionTestNonNull *instruction) { 15393 IrInstruction *value = instruction->value->child; 15394 if (type_is_invalid(value->value.type)) 15395 return ira->codegen->invalid_instruction; 15396 15397 ZigType *type_entry = value->value.type; 15398 15399 if (type_entry->id == ZigTypeIdOptional) { 15400 if (instr_is_comptime(value)) { 15401 ConstExprValue *maybe_val = ir_resolve_const(ira, value, UndefBad); 15402 if (!maybe_val) 15403 return ira->codegen->invalid_instruction; 15404 15405 return ir_const_bool(ira, &instruction->base, !optional_value_is_null(maybe_val)); 15406 } 15407 15408 IrInstruction *result = ir_build_test_nonnull(&ira->new_irb, 15409 instruction->base.scope, instruction->base.source_node, value); 15410 result->value.type = ira->codegen->builtin_types.entry_bool; 15411 return result; 15412 } else if (type_entry->id == ZigTypeIdNull) { 15413 return ir_const_bool(ira, &instruction->base, false); 15414 } else { 15415 return ir_const_bool(ira, &instruction->base, true); 15416 } 15417 } 15418 15419 static IrInstruction *ir_analyze_instruction_unwrap_maybe(IrAnalyze *ira, 15420 IrInstructionUnwrapOptional *unwrap_maybe_instruction) 15421 { 15422 IrInstruction *value = unwrap_maybe_instruction->value->child; 15423 if (type_is_invalid(value->value.type)) 15424 return ira->codegen->invalid_instruction; 15425 15426 ZigType *ptr_type = value->value.type; 15427 assert(ptr_type->id == ZigTypeIdPointer); 15428 15429 ZigType *type_entry = ptr_type->data.pointer.child_type; 15430 if (type_is_invalid(type_entry)) { 15431 return ira->codegen->invalid_instruction; 15432 } else if (type_entry->id != ZigTypeIdOptional) { 15433 ir_add_error_node(ira, unwrap_maybe_instruction->value->source_node, 15434 buf_sprintf("expected optional type, found '%s'", buf_ptr(&type_entry->name))); 15435 return ira->codegen->invalid_instruction; 15436 } 15437 ZigType *child_type = type_entry->data.maybe.child_type; 15438 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, 15439 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, PtrLenSingle, 0, 0, 0); 15440 15441 if (instr_is_comptime(value)) { 15442 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 15443 if (!val) 15444 return ira->codegen->invalid_instruction; 15445 ConstExprValue *maybe_val = ir_const_ptr_pointee(ira, val, unwrap_maybe_instruction->base.source_node); 15446 if (maybe_val == nullptr) 15447 return ira->codegen->invalid_instruction; 15448 15449 if (val->data.x_ptr.mut != ConstPtrMutRuntimeVar) { 15450 if (optional_value_is_null(maybe_val)) { 15451 ir_add_error(ira, &unwrap_maybe_instruction->base, buf_sprintf("unable to unwrap null")); 15452 return ira->codegen->invalid_instruction; 15453 } 15454 IrInstruction *result = ir_const(ira, &unwrap_maybe_instruction->base, result_type); 15455 ConstExprValue *out_val = &result->value; 15456 out_val->data.x_ptr.special = ConstPtrSpecialRef; 15457 out_val->data.x_ptr.mut = val->data.x_ptr.mut; 15458 if (type_is_codegen_pointer(child_type)) { 15459 out_val->data.x_ptr.data.ref.pointee = maybe_val; 15460 } else { 15461 out_val->data.x_ptr.data.ref.pointee = maybe_val->data.x_optional; 15462 } 15463 return result; 15464 } 15465 } 15466 15467 IrInstruction *result = ir_build_unwrap_maybe(&ira->new_irb, 15468 unwrap_maybe_instruction->base.scope, unwrap_maybe_instruction->base.source_node, 15469 value, unwrap_maybe_instruction->safety_check_on); 15470 result->value.type = result_type; 15471 return result; 15472 } 15473 15474 static IrInstruction *ir_analyze_instruction_ctz(IrAnalyze *ira, IrInstructionCtz *ctz_instruction) { 15475 IrInstruction *value = ctz_instruction->value->child; 15476 if (type_is_invalid(value->value.type)) { 15477 return ira->codegen->invalid_instruction; 15478 } else if (value->value.type->id == ZigTypeIdInt) { 15479 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, 15480 value->value.type->data.integral.bit_count); 15481 if (value->value.special != ConstValSpecialRuntime) { 15482 size_t result_usize = bigint_ctz(&value->value.data.x_bigint, 15483 value->value.type->data.integral.bit_count); 15484 IrInstruction *result = ir_const(ira, &ctz_instruction->base, return_type); 15485 bigint_init_unsigned(&result->value.data.x_bigint, result_usize); 15486 return result; 15487 } 15488 15489 IrInstruction *result = ir_build_ctz(&ira->new_irb, 15490 ctz_instruction->base.scope, ctz_instruction->base.source_node, value); 15491 result->value.type = return_type; 15492 return result; 15493 } else { 15494 ir_add_error_node(ira, ctz_instruction->base.source_node, 15495 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); 15496 return ira->codegen->invalid_instruction; 15497 } 15498 } 15499 15500 static IrInstruction *ir_analyze_instruction_clz(IrAnalyze *ira, IrInstructionClz *clz_instruction) { 15501 IrInstruction *value = clz_instruction->value->child; 15502 if (type_is_invalid(value->value.type)) { 15503 return ira->codegen->invalid_instruction; 15504 } else if (value->value.type->id == ZigTypeIdInt) { 15505 ZigType *return_type = get_smallest_unsigned_int_type(ira->codegen, 15506 value->value.type->data.integral.bit_count); 15507 if (value->value.special != ConstValSpecialRuntime) { 15508 size_t result_usize = bigint_clz(&value->value.data.x_bigint, 15509 value->value.type->data.integral.bit_count); 15510 IrInstruction *result = ir_const(ira, &clz_instruction->base, return_type); 15511 bigint_init_unsigned(&result->value.data.x_bigint, result_usize); 15512 return result; 15513 } 15514 15515 IrInstruction *result = ir_build_clz(&ira->new_irb, 15516 clz_instruction->base.scope, clz_instruction->base.source_node, value); 15517 result->value.type = return_type; 15518 return result; 15519 } else { 15520 ir_add_error_node(ira, clz_instruction->base.source_node, 15521 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); 15522 return ira->codegen->invalid_instruction; 15523 } 15524 } 15525 15526 static IrInstruction *ir_analyze_instruction_pop_count(IrAnalyze *ira, IrInstructionPopCount *instruction) { 15527 IrInstruction *value = instruction->value->child; 15528 if (type_is_invalid(value->value.type)) 15529 return ira->codegen->invalid_instruction; 15530 15531 if (value->value.type->id != ZigTypeIdInt && value->value.type->id != ZigTypeIdComptimeInt) { 15532 ir_add_error(ira, value, 15533 buf_sprintf("expected integer type, found '%s'", buf_ptr(&value->value.type->name))); 15534 return ira->codegen->invalid_instruction; 15535 } 15536 15537 if (instr_is_comptime(value)) { 15538 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 15539 if (!val) 15540 return ira->codegen->invalid_instruction; 15541 if (bigint_cmp_zero(&val->data.x_bigint) != CmpLT) { 15542 size_t result = bigint_popcount_unsigned(&val->data.x_bigint); 15543 return ir_const_unsigned(ira, &instruction->base, result); 15544 } 15545 if (value->value.type->id == ZigTypeIdComptimeInt) { 15546 Buf *val_buf = buf_alloc(); 15547 bigint_append_buf(val_buf, &val->data.x_bigint, 10); 15548 ir_add_error(ira, &instruction->base, 15549 buf_sprintf("@popCount on negative %s value %s", 15550 buf_ptr(&value->value.type->name), buf_ptr(val_buf))); 15551 return ira->codegen->invalid_instruction; 15552 } 15553 size_t result = bigint_popcount_signed(&val->data.x_bigint, value->value.type->data.integral.bit_count); 15554 return ir_const_unsigned(ira, &instruction->base, result); 15555 } 15556 15557 IrInstruction *result = ir_build_pop_count(&ira->new_irb, instruction->base.scope, 15558 instruction->base.source_node, value); 15559 result->value.type = get_smallest_unsigned_int_type(ira->codegen, value->value.type->data.integral.bit_count); 15560 return result; 15561 } 15562 15563 static IrInstruction *ir_analyze_union_tag(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value) { 15564 if (type_is_invalid(value->value.type)) 15565 return ira->codegen->invalid_instruction; 15566 15567 if (value->value.type->id == ZigTypeIdEnum) { 15568 return value; 15569 } 15570 15571 if (value->value.type->id != ZigTypeIdUnion) { 15572 ir_add_error(ira, value, 15573 buf_sprintf("expected enum or union type, found '%s'", buf_ptr(&value->value.type->name))); 15574 return ira->codegen->invalid_instruction; 15575 } 15576 if (!value->value.type->data.unionation.have_explicit_tag_type && !source_instr->is_gen) { 15577 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("union has no associated enum")); 15578 if (value->value.type->data.unionation.decl_node != nullptr) { 15579 add_error_note(ira->codegen, msg, value->value.type->data.unionation.decl_node, 15580 buf_sprintf("declared here")); 15581 } 15582 return ira->codegen->invalid_instruction; 15583 } 15584 15585 ZigType *tag_type = value->value.type->data.unionation.tag_type; 15586 assert(tag_type->id == ZigTypeIdEnum); 15587 15588 if (instr_is_comptime(value)) { 15589 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 15590 if (!val) 15591 return ira->codegen->invalid_instruction; 15592 15593 IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(&ira->new_irb, 15594 source_instr->scope, source_instr->source_node); 15595 const_instruction->base.value.type = tag_type; 15596 const_instruction->base.value.special = ConstValSpecialStatic; 15597 bigint_init_bigint(&const_instruction->base.value.data.x_enum_tag, &val->data.x_union.tag); 15598 return &const_instruction->base; 15599 } 15600 15601 IrInstruction *result = ir_build_union_tag(&ira->new_irb, source_instr->scope, source_instr->source_node, value); 15602 result->value.type = tag_type; 15603 return result; 15604 } 15605 15606 static IrInstruction *ir_analyze_instruction_switch_br(IrAnalyze *ira, 15607 IrInstructionSwitchBr *switch_br_instruction) 15608 { 15609 IrInstruction *target_value = switch_br_instruction->target_value->child; 15610 if (type_is_invalid(target_value->value.type)) 15611 return ir_unreach_error(ira); 15612 15613 if (switch_br_instruction->switch_prongs_void != nullptr) { 15614 if (type_is_invalid(switch_br_instruction->switch_prongs_void->child->value.type)) { 15615 return ir_unreach_error(ira); 15616 } 15617 } 15618 15619 15620 size_t case_count = switch_br_instruction->case_count; 15621 15622 bool is_comptime; 15623 if (!ir_resolve_comptime(ira, switch_br_instruction->is_comptime->child, &is_comptime)) 15624 return ira->codegen->invalid_instruction; 15625 15626 if (is_comptime || instr_is_comptime(target_value)) { 15627 ConstExprValue *target_val = ir_resolve_const(ira, target_value, UndefBad); 15628 if (!target_val) 15629 return ir_unreach_error(ira); 15630 15631 IrBasicBlock *old_dest_block = switch_br_instruction->else_block; 15632 for (size_t i = 0; i < case_count; i += 1) { 15633 IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 15634 IrInstruction *case_value = old_case->value->child; 15635 if (type_is_invalid(case_value->value.type)) 15636 return ir_unreach_error(ira); 15637 15638 if (case_value->value.type->id == ZigTypeIdEnum) { 15639 case_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, case_value); 15640 if (type_is_invalid(case_value->value.type)) 15641 return ir_unreach_error(ira); 15642 } 15643 15644 IrInstruction *casted_case_value = ir_implicit_cast(ira, case_value, target_value->value.type); 15645 if (type_is_invalid(casted_case_value->value.type)) 15646 return ir_unreach_error(ira); 15647 15648 ConstExprValue *case_val = ir_resolve_const(ira, casted_case_value, UndefBad); 15649 if (!case_val) 15650 return ir_unreach_error(ira); 15651 15652 if (const_values_equal(ira->codegen, target_val, case_val)) { 15653 old_dest_block = old_case->block; 15654 break; 15655 } 15656 } 15657 15658 if (is_comptime || old_dest_block->ref_count == 1) { 15659 return ir_inline_bb(ira, &switch_br_instruction->base, old_dest_block); 15660 } else { 15661 IrBasicBlock *new_dest_block = ir_get_new_bb(ira, old_dest_block, &switch_br_instruction->base); 15662 IrInstruction *result = ir_build_br(&ira->new_irb, 15663 switch_br_instruction->base.scope, switch_br_instruction->base.source_node, 15664 new_dest_block, nullptr); 15665 result->value.type = ira->codegen->builtin_types.entry_unreachable; 15666 return ir_finish_anal(ira, result); 15667 } 15668 } 15669 15670 IrInstructionSwitchBrCase *cases = allocate<IrInstructionSwitchBrCase>(case_count); 15671 for (size_t i = 0; i < case_count; i += 1) { 15672 IrInstructionSwitchBrCase *old_case = &switch_br_instruction->cases[i]; 15673 IrInstructionSwitchBrCase *new_case = &cases[i]; 15674 new_case->block = ir_get_new_bb(ira, old_case->block, &switch_br_instruction->base); 15675 new_case->value = ira->codegen->invalid_instruction; 15676 15677 // Calling ir_get_new_bb set the ref_instruction on the new basic block. 15678 // However a switch br may branch to the same basic block which would trigger an 15679 // incorrect re-generation of the block. So we set it to null here and assign 15680 // it back after the loop. 15681 new_case->block->ref_instruction = nullptr; 15682 15683 IrInstruction *old_value = old_case->value; 15684 IrInstruction *new_value = old_value->child; 15685 if (type_is_invalid(new_value->value.type)) 15686 continue; 15687 15688 if (new_value->value.type->id == ZigTypeIdEnum) { 15689 new_value = ir_analyze_union_tag(ira, &switch_br_instruction->base, new_value); 15690 if (type_is_invalid(new_value->value.type)) 15691 continue; 15692 } 15693 15694 IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, target_value->value.type); 15695 if (type_is_invalid(casted_new_value->value.type)) 15696 continue; 15697 15698 if (!ir_resolve_const(ira, casted_new_value, UndefBad)) 15699 continue; 15700 15701 new_case->value = casted_new_value; 15702 } 15703 15704 for (size_t i = 0; i < case_count; i += 1) { 15705 IrInstructionSwitchBrCase *new_case = &cases[i]; 15706 if (new_case->value == ira->codegen->invalid_instruction) 15707 return ir_unreach_error(ira); 15708 new_case->block->ref_instruction = &switch_br_instruction->base; 15709 } 15710 15711 IrBasicBlock *new_else_block = ir_get_new_bb(ira, switch_br_instruction->else_block, &switch_br_instruction->base); 15712 IrInstruction *result = ir_build_switch_br(&ira->new_irb, 15713 switch_br_instruction->base.scope, switch_br_instruction->base.source_node, 15714 target_value, new_else_block, case_count, cases, nullptr, nullptr); 15715 result->value.type = ira->codegen->builtin_types.entry_unreachable; 15716 return ir_finish_anal(ira, result); 15717 } 15718 15719 static IrInstruction *ir_analyze_instruction_switch_target(IrAnalyze *ira, 15720 IrInstructionSwitchTarget *switch_target_instruction) 15721 { 15722 Error err; 15723 IrInstruction *target_value_ptr = switch_target_instruction->target_value_ptr->child; 15724 if (type_is_invalid(target_value_ptr->value.type)) 15725 return ira->codegen->invalid_instruction; 15726 15727 if (target_value_ptr->value.type->id == ZigTypeIdMetaType) { 15728 assert(instr_is_comptime(target_value_ptr)); 15729 ZigType *ptr_type = target_value_ptr->value.data.x_type; 15730 assert(ptr_type->id == ZigTypeIdPointer); 15731 return ir_const_type(ira, &switch_target_instruction->base, ptr_type->data.pointer.child_type); 15732 } 15733 15734 if (target_value_ptr->value.type->id != ZigTypeIdPointer) { 15735 ir_add_error(ira, target_value_ptr, buf_sprintf("invalid deref on switch target")); 15736 return ira->codegen->invalid_instruction; 15737 } 15738 15739 ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type; 15740 ConstExprValue *pointee_val = nullptr; 15741 if (instr_is_comptime(target_value_ptr)) { 15742 pointee_val = ir_const_ptr_pointee(ira, &target_value_ptr->value, target_value_ptr->source_node); 15743 if (pointee_val == nullptr) 15744 return ira->codegen->invalid_instruction; 15745 15746 if (pointee_val->special == ConstValSpecialRuntime) 15747 pointee_val = nullptr; 15748 } 15749 if ((err = ensure_complete_type(ira->codegen, target_type))) 15750 return ira->codegen->invalid_instruction; 15751 15752 switch (target_type->id) { 15753 case ZigTypeIdInvalid: 15754 zig_unreachable(); 15755 case ZigTypeIdMetaType: 15756 case ZigTypeIdVoid: 15757 case ZigTypeIdBool: 15758 case ZigTypeIdInt: 15759 case ZigTypeIdFloat: 15760 case ZigTypeIdComptimeFloat: 15761 case ZigTypeIdComptimeInt: 15762 case ZigTypeIdPointer: 15763 case ZigTypeIdPromise: 15764 case ZigTypeIdFn: 15765 case ZigTypeIdNamespace: 15766 case ZigTypeIdErrorSet: { 15767 if (pointee_val) { 15768 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, nullptr); 15769 copy_const_val(&result->value, pointee_val, true); 15770 result->value.type = target_type; 15771 return result; 15772 } 15773 15774 IrInstruction *result = ir_build_load_ptr(&ira->new_irb, 15775 switch_target_instruction->base.scope, switch_target_instruction->base.source_node, 15776 target_value_ptr); 15777 result->value.type = target_type; 15778 return result; 15779 } 15780 case ZigTypeIdUnion: { 15781 AstNode *decl_node = target_type->data.unionation.decl_node; 15782 if (!decl_node->data.container_decl.auto_enum && 15783 decl_node->data.container_decl.init_arg_expr == nullptr) 15784 { 15785 ErrorMsg *msg = ir_add_error(ira, target_value_ptr, 15786 buf_sprintf("switch on union which has no attached enum")); 15787 add_error_note(ira->codegen, msg, decl_node, 15788 buf_sprintf("consider 'union(enum)' here")); 15789 return ira->codegen->invalid_instruction; 15790 } 15791 ZigType *tag_type = target_type->data.unionation.tag_type; 15792 assert(tag_type != nullptr); 15793 assert(tag_type->id == ZigTypeIdEnum); 15794 if (pointee_val) { 15795 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, tag_type); 15796 bigint_init_bigint(&result->value.data.x_enum_tag, &pointee_val->data.x_union.tag); 15797 return result; 15798 } 15799 if (tag_type->data.enumeration.src_field_count == 1) { 15800 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, tag_type); 15801 TypeEnumField *only_field = &tag_type->data.enumeration.fields[0]; 15802 bigint_init_bigint(&result->value.data.x_enum_tag, &only_field->value); 15803 return result; 15804 } 15805 15806 IrInstruction *union_value = ir_build_load_ptr(&ira->new_irb, switch_target_instruction->base.scope, 15807 switch_target_instruction->base.source_node, target_value_ptr); 15808 union_value->value.type = target_type; 15809 15810 IrInstruction *union_tag_inst = ir_build_union_tag(&ira->new_irb, switch_target_instruction->base.scope, 15811 switch_target_instruction->base.source_node, union_value); 15812 union_tag_inst->value.type = tag_type; 15813 return union_tag_inst; 15814 } 15815 case ZigTypeIdEnum: { 15816 if ((err = type_resolve(ira->codegen, target_type, ResolveStatusZeroBitsKnown))) 15817 return ira->codegen->invalid_instruction; 15818 if (target_type->data.enumeration.src_field_count < 2) { 15819 TypeEnumField *only_field = &target_type->data.enumeration.fields[0]; 15820 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type); 15821 bigint_init_bigint(&result->value.data.x_enum_tag, &only_field->value); 15822 return result; 15823 } 15824 15825 if (pointee_val) { 15826 IrInstruction *result = ir_const(ira, &switch_target_instruction->base, target_type); 15827 bigint_init_bigint(&result->value.data.x_enum_tag, &pointee_val->data.x_enum_tag); 15828 return result; 15829 } 15830 15831 IrInstruction *enum_value = ir_build_load_ptr(&ira->new_irb, switch_target_instruction->base.scope, 15832 switch_target_instruction->base.source_node, target_value_ptr); 15833 enum_value->value.type = target_type; 15834 return enum_value; 15835 } 15836 case ZigTypeIdErrorUnion: 15837 case ZigTypeIdUnreachable: 15838 case ZigTypeIdArray: 15839 case ZigTypeIdStruct: 15840 case ZigTypeIdUndefined: 15841 case ZigTypeIdNull: 15842 case ZigTypeIdOptional: 15843 case ZigTypeIdBoundFn: 15844 case ZigTypeIdArgTuple: 15845 case ZigTypeIdOpaque: 15846 ir_add_error(ira, &switch_target_instruction->base, 15847 buf_sprintf("invalid switch target type '%s'", buf_ptr(&target_type->name))); 15848 return ira->codegen->invalid_instruction; 15849 } 15850 zig_unreachable(); 15851 } 15852 15853 static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstructionSwitchVar *instruction) { 15854 IrInstruction *target_value_ptr = instruction->target_value_ptr->child; 15855 if (type_is_invalid(target_value_ptr->value.type)) 15856 return ira->codegen->invalid_instruction; 15857 15858 IrInstruction *prong_value = instruction->prong_value->child; 15859 if (type_is_invalid(prong_value->value.type)) 15860 return ira->codegen->invalid_instruction; 15861 15862 assert(target_value_ptr->value.type->id == ZigTypeIdPointer); 15863 ZigType *target_type = target_value_ptr->value.type->data.pointer.child_type; 15864 if (target_type->id == ZigTypeIdUnion) { 15865 ConstExprValue *prong_val = ir_resolve_const(ira, prong_value, UndefBad); 15866 if (!prong_val) 15867 return ira->codegen->invalid_instruction; 15868 15869 assert(prong_value->value.type->id == ZigTypeIdEnum); 15870 TypeUnionField *field = find_union_field_by_tag(target_type, &prong_val->data.x_enum_tag); 15871 15872 if (instr_is_comptime(target_value_ptr)) { 15873 ConstExprValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad); 15874 if (!target_value_ptr) 15875 return ira->codegen->invalid_instruction; 15876 15877 ConstExprValue *pointee_val = ir_const_ptr_pointee(ira, target_val_ptr, instruction->base.source_node); 15878 if (pointee_val == nullptr) 15879 return ira->codegen->invalid_instruction; 15880 15881 IrInstruction *result = ir_const(ira, &instruction->base, 15882 get_pointer_to_type(ira->codegen, field->type_entry, 15883 target_val_ptr->type->data.pointer.is_const)); 15884 ConstExprValue *out_val = &result->value; 15885 out_val->data.x_ptr.special = ConstPtrSpecialRef; 15886 out_val->data.x_ptr.mut = target_val_ptr->data.x_ptr.mut; 15887 out_val->data.x_ptr.data.ref.pointee = pointee_val->data.x_union.payload; 15888 return result; 15889 } 15890 15891 IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, 15892 instruction->base.scope, instruction->base.source_node, target_value_ptr, field); 15893 result->value.type = get_pointer_to_type(ira->codegen, field->type_entry, 15894 target_value_ptr->value.type->data.pointer.is_const); 15895 return result; 15896 } else { 15897 ir_add_error(ira, &instruction->base, 15898 buf_sprintf("switch on type '%s' provides no expression parameter", buf_ptr(&target_type->name))); 15899 return ira->codegen->invalid_instruction; 15900 } 15901 } 15902 15903 static IrInstruction *ir_analyze_instruction_union_tag(IrAnalyze *ira, IrInstructionUnionTag *instruction) { 15904 IrInstruction *value = instruction->value->child; 15905 return ir_analyze_union_tag(ira, &instruction->base, value); 15906 } 15907 15908 static IrInstruction *ir_analyze_instruction_import(IrAnalyze *ira, IrInstructionImport *import_instruction) { 15909 Error err; 15910 15911 IrInstruction *name_value = import_instruction->name->child; 15912 Buf *import_target_str = ir_resolve_str(ira, name_value); 15913 if (!import_target_str) 15914 return ira->codegen->invalid_instruction; 15915 15916 AstNode *source_node = import_instruction->base.source_node; 15917 ImportTableEntry *import = source_node->owner; 15918 15919 Buf *import_target_path; 15920 Buf *search_dir; 15921 assert(import->package); 15922 PackageTableEntry *target_package; 15923 auto package_entry = import->package->package_table.maybe_get(import_target_str); 15924 if (package_entry) { 15925 target_package = package_entry->value; 15926 import_target_path = &target_package->root_src_path; 15927 search_dir = &target_package->root_src_dir; 15928 } else { 15929 // try it as a filename 15930 target_package = import->package; 15931 import_target_path = import_target_str; 15932 15933 // search relative to importing file 15934 search_dir = buf_alloc(); 15935 os_path_dirname(import->path, search_dir); 15936 } 15937 15938 Buf full_path = BUF_INIT; 15939 os_path_join(search_dir, import_target_path, &full_path); 15940 15941 Buf *import_code = buf_alloc(); 15942 Buf *resolved_path = buf_alloc(); 15943 15944 Buf *resolve_paths[] = { &full_path, }; 15945 *resolved_path = os_path_resolve(resolve_paths, 1); 15946 15947 auto import_entry = ira->codegen->import_table.maybe_get(resolved_path); 15948 if (import_entry) { 15949 IrInstruction *result = ir_const(ira, &import_instruction->base, 15950 ira->codegen->builtin_types.entry_namespace); 15951 result->value.data.x_import = import_entry->value; 15952 return result; 15953 } 15954 15955 if ((err = file_fetch(ira->codegen, resolved_path, import_code))) { 15956 if (err == ErrorFileNotFound) { 15957 ir_add_error_node(ira, source_node, 15958 buf_sprintf("unable to find '%s'", buf_ptr(import_target_path))); 15959 return ira->codegen->invalid_instruction; 15960 } else { 15961 ir_add_error_node(ira, source_node, 15962 buf_sprintf("unable to open '%s': %s", buf_ptr(&full_path), err_str(err))); 15963 return ira->codegen->invalid_instruction; 15964 } 15965 } 15966 15967 ImportTableEntry *target_import = add_source_file(ira->codegen, target_package, resolved_path, import_code); 15968 15969 scan_import(ira->codegen, target_import); 15970 15971 IrInstruction *result = ir_const(ira, &import_instruction->base, ira->codegen->builtin_types.entry_namespace); 15972 result->value.data.x_import = target_import; 15973 return result; 15974 } 15975 15976 static IrInstruction *ir_analyze_instruction_array_len(IrAnalyze *ira, 15977 IrInstructionArrayLen *array_len_instruction) 15978 { 15979 IrInstruction *array_value = array_len_instruction->array_value->child; 15980 ZigType *type_entry = array_value->value.type; 15981 if (type_is_invalid(type_entry)) { 15982 return ira->codegen->invalid_instruction; 15983 } else if (type_entry->id == ZigTypeIdArray) { 15984 return ir_const_usize(ira, &array_len_instruction->base, 15985 type_entry->data.array.len); 15986 } else if (is_slice(type_entry)) { 15987 if (array_value->value.special != ConstValSpecialRuntime) { 15988 ConstExprValue *len_val = &array_value->value.data.x_struct.fields[slice_len_index]; 15989 if (len_val->special != ConstValSpecialRuntime) { 15990 return ir_const_usize(ira, &array_len_instruction->base, 15991 bigint_as_unsigned(&len_val->data.x_bigint)); 15992 } 15993 } 15994 TypeStructField *field = &type_entry->data.structure.fields[slice_len_index]; 15995 IrInstruction *len_ptr = ir_build_struct_field_ptr(&ira->new_irb, array_len_instruction->base.scope, 15996 array_len_instruction->base.source_node, array_value, field); 15997 len_ptr->value.type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_usize, true); 15998 IrInstruction *result = ir_build_load_ptr(&ira->new_irb, 15999 array_len_instruction->base.scope, array_len_instruction->base.source_node, len_ptr); 16000 result->value.type = ira->codegen->builtin_types.entry_usize; 16001 return result; 16002 } else { 16003 ir_add_error_node(ira, array_len_instruction->base.source_node, 16004 buf_sprintf("type '%s' has no field 'len'", buf_ptr(&array_value->value.type->name))); 16005 return ira->codegen->invalid_instruction; 16006 } 16007 } 16008 16009 static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRef *ref_instruction) { 16010 IrInstruction *value = ref_instruction->value->child; 16011 if (type_is_invalid(value->value.type)) 16012 return ira->codegen->invalid_instruction; 16013 return ir_get_ref(ira, &ref_instruction->base, value, ref_instruction->is_const, ref_instruction->is_volatile); 16014 } 16015 16016 static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, 16017 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) 16018 { 16019 Error err; 16020 assert(container_type->id == ZigTypeIdUnion); 16021 16022 if ((err = ensure_complete_type(ira->codegen, container_type))) 16023 return ira->codegen->invalid_instruction; 16024 16025 if (instr_field_count != 1) { 16026 ir_add_error(ira, instruction, 16027 buf_sprintf("union initialization expects exactly one field")); 16028 return ira->codegen->invalid_instruction; 16029 } 16030 16031 IrInstructionContainerInitFieldsField *field = &fields[0]; 16032 IrInstruction *field_value = field->value->child; 16033 if (type_is_invalid(field_value->value.type)) 16034 return ira->codegen->invalid_instruction; 16035 16036 TypeUnionField *type_field = find_union_type_field(container_type, field->name); 16037 if (!type_field) { 16038 ir_add_error_node(ira, field->source_node, 16039 buf_sprintf("no member named '%s' in union '%s'", 16040 buf_ptr(field->name), buf_ptr(&container_type->name))); 16041 return ira->codegen->invalid_instruction; 16042 } 16043 16044 if (type_is_invalid(type_field->type_entry)) 16045 return ira->codegen->invalid_instruction; 16046 16047 IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); 16048 if (casted_field_value == ira->codegen->invalid_instruction) 16049 return ira->codegen->invalid_instruction; 16050 16051 if ((err = type_resolve(ira->codegen, casted_field_value->value.type, ResolveStatusZeroBitsKnown))) 16052 return ira->codegen->invalid_instruction; 16053 16054 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope); 16055 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime || 16056 !type_has_bits(casted_field_value->value.type)) 16057 { 16058 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); 16059 if (!field_val) 16060 return ira->codegen->invalid_instruction; 16061 16062 IrInstruction *result = ir_const(ira, instruction, container_type); 16063 ConstExprValue *out_val = &result->value; 16064 out_val->data.x_union.payload = field_val; 16065 out_val->data.x_union.tag = type_field->enum_field->value; 16066 16067 ConstParent *parent = get_const_val_parent(ira->codegen, field_val); 16068 if (parent != nullptr) { 16069 parent->id = ConstParentIdUnion; 16070 parent->data.p_union.union_val = out_val; 16071 } 16072 16073 return result; 16074 } 16075 16076 IrInstruction *new_instruction = ir_build_union_init(&ira->new_irb, 16077 instruction->scope, instruction->source_node, 16078 container_type, type_field, casted_field_value); 16079 new_instruction->value.type = container_type; 16080 ir_add_alloca(ira, new_instruction, container_type); 16081 return new_instruction; 16082 } 16083 16084 static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruction *instruction, 16085 ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields) 16086 { 16087 Error err; 16088 if (container_type->id == ZigTypeIdUnion) { 16089 return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, fields); 16090 } 16091 if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { 16092 ir_add_error(ira, instruction, 16093 buf_sprintf("type '%s' does not support struct initialization syntax", 16094 buf_ptr(&container_type->name))); 16095 return ira->codegen->invalid_instruction; 16096 } 16097 16098 if ((err = ensure_complete_type(ira->codegen, container_type))) 16099 return ira->codegen->invalid_instruction; 16100 16101 size_t actual_field_count = container_type->data.structure.src_field_count; 16102 16103 IrInstruction *first_non_const_instruction = nullptr; 16104 16105 AstNode **field_assign_nodes = allocate<AstNode *>(actual_field_count); 16106 16107 IrInstructionStructInitField *new_fields = allocate<IrInstructionStructInitField>(actual_field_count); 16108 16109 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope); 16110 16111 ConstExprValue const_val = {}; 16112 const_val.special = ConstValSpecialStatic; 16113 const_val.type = container_type; 16114 const_val.data.x_struct.fields = create_const_vals(actual_field_count); 16115 for (size_t i = 0; i < instr_field_count; i += 1) { 16116 IrInstructionContainerInitFieldsField *field = &fields[i]; 16117 16118 IrInstruction *field_value = field->value->child; 16119 if (type_is_invalid(field_value->value.type)) 16120 return ira->codegen->invalid_instruction; 16121 16122 TypeStructField *type_field = find_struct_type_field(container_type, field->name); 16123 if (!type_field) { 16124 ir_add_error_node(ira, field->source_node, 16125 buf_sprintf("no member named '%s' in struct '%s'", 16126 buf_ptr(field->name), buf_ptr(&container_type->name))); 16127 return ira->codegen->invalid_instruction; 16128 } 16129 16130 if (type_is_invalid(type_field->type_entry)) 16131 return ira->codegen->invalid_instruction; 16132 16133 IrInstruction *casted_field_value = ir_implicit_cast(ira, field_value, type_field->type_entry); 16134 if (casted_field_value == ira->codegen->invalid_instruction) 16135 return ira->codegen->invalid_instruction; 16136 16137 size_t field_index = type_field->src_index; 16138 AstNode *existing_assign_node = field_assign_nodes[field_index]; 16139 if (existing_assign_node) { 16140 ErrorMsg *msg = ir_add_error_node(ira, field->source_node, buf_sprintf("duplicate field")); 16141 add_error_note(ira->codegen, msg, existing_assign_node, buf_sprintf("other field here")); 16142 return ira->codegen->invalid_instruction; 16143 } 16144 field_assign_nodes[field_index] = field->source_node; 16145 16146 new_fields[field_index].value = casted_field_value; 16147 new_fields[field_index].type_struct_field = type_field; 16148 16149 if (const_val.special == ConstValSpecialStatic) { 16150 if (is_comptime || casted_field_value->value.special != ConstValSpecialRuntime) { 16151 ConstExprValue *field_val = ir_resolve_const(ira, casted_field_value, UndefOk); 16152 if (!field_val) 16153 return ira->codegen->invalid_instruction; 16154 16155 copy_const_val(&const_val.data.x_struct.fields[field_index], field_val, true); 16156 } else { 16157 first_non_const_instruction = casted_field_value; 16158 const_val.special = ConstValSpecialRuntime; 16159 } 16160 } 16161 } 16162 16163 bool any_missing = false; 16164 for (size_t i = 0; i < actual_field_count; i += 1) { 16165 if (!field_assign_nodes[i]) { 16166 ir_add_error_node(ira, instruction->source_node, 16167 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name))); 16168 any_missing = true; 16169 } 16170 } 16171 if (any_missing) 16172 return ira->codegen->invalid_instruction; 16173 16174 if (const_val.special == ConstValSpecialStatic) { 16175 IrInstruction *result = ir_const(ira, instruction, nullptr); 16176 ConstExprValue *out_val = &result->value; 16177 // TODO copy_const_val? 16178 *out_val = const_val; 16179 result->value.type = container_type; 16180 16181 for (size_t i = 0; i < instr_field_count; i += 1) { 16182 ConstExprValue *field_val = &out_val->data.x_struct.fields[i]; 16183 ConstParent *parent = get_const_val_parent(ira->codegen, field_val); 16184 if (parent != nullptr) { 16185 parent->id = ConstParentIdStruct; 16186 parent->data.p_struct.field_index = i; 16187 parent->data.p_struct.struct_val = out_val; 16188 } 16189 } 16190 16191 return result; 16192 } 16193 16194 if (is_comptime) { 16195 ir_add_error_node(ira, first_non_const_instruction->source_node, 16196 buf_sprintf("unable to evaluate constant expression")); 16197 return ira->codegen->invalid_instruction; 16198 } 16199 16200 IrInstruction *new_instruction = ir_build_struct_init(&ira->new_irb, 16201 instruction->scope, instruction->source_node, 16202 container_type, actual_field_count, new_fields); 16203 new_instruction->value.type = container_type; 16204 ir_add_alloca(ira, new_instruction, container_type); 16205 return new_instruction; 16206 } 16207 16208 static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, 16209 IrInstructionContainerInitList *instruction) 16210 { 16211 IrInstruction *container_type_value = instruction->container_type->child; 16212 if (type_is_invalid(container_type_value->value.type)) 16213 return ira->codegen->invalid_instruction; 16214 16215 size_t elem_count = instruction->item_count; 16216 if (container_type_value->value.type->id == ZigTypeIdMetaType) { 16217 ZigType *container_type = ir_resolve_type(ira, container_type_value); 16218 if (type_is_invalid(container_type)) 16219 return ira->codegen->invalid_instruction; 16220 16221 if (container_type->id == ZigTypeIdStruct && !is_slice(container_type) && elem_count == 0) { 16222 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 16223 0, nullptr); 16224 } else if (is_slice(container_type) || container_type->id == ZigTypeIdArray) { 16225 // array is same as slice init but we make a compile error if the length is wrong 16226 ZigType *child_type; 16227 if (container_type->id == ZigTypeIdArray) { 16228 child_type = container_type->data.array.child_type; 16229 if (container_type->data.array.len != elem_count) { 16230 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count); 16231 16232 ir_add_error(ira, &instruction->base, 16233 buf_sprintf("expected %s literal, found %s literal", 16234 buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); 16235 return ira->codegen->invalid_instruction; 16236 } 16237 } else { 16238 ZigType *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry; 16239 assert(pointer_type->id == ZigTypeIdPointer); 16240 child_type = pointer_type->data.pointer.child_type; 16241 } 16242 16243 ZigType *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count); 16244 16245 ConstExprValue const_val = {}; 16246 const_val.special = ConstValSpecialStatic; 16247 const_val.type = fixed_size_array_type; 16248 const_val.data.x_array.data.s_none.elements = create_const_vals(elem_count); 16249 16250 bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->base.scope); 16251 16252 IrInstruction **new_items = allocate<IrInstruction *>(elem_count); 16253 16254 IrInstruction *first_non_const_instruction = nullptr; 16255 16256 for (size_t i = 0; i < elem_count; i += 1) { 16257 IrInstruction *arg_value = instruction->items[i]->child; 16258 if (type_is_invalid(arg_value->value.type)) 16259 return ira->codegen->invalid_instruction; 16260 16261 IrInstruction *casted_arg = ir_implicit_cast(ira, arg_value, child_type); 16262 if (casted_arg == ira->codegen->invalid_instruction) 16263 return ira->codegen->invalid_instruction; 16264 16265 new_items[i] = casted_arg; 16266 16267 if (const_val.special == ConstValSpecialStatic) { 16268 if (is_comptime || casted_arg->value.special != ConstValSpecialRuntime) { 16269 ConstExprValue *elem_val = ir_resolve_const(ira, casted_arg, UndefBad); 16270 if (!elem_val) 16271 return ira->codegen->invalid_instruction; 16272 16273 copy_const_val(&const_val.data.x_array.data.s_none.elements[i], elem_val, true); 16274 } else { 16275 first_non_const_instruction = casted_arg; 16276 const_val.special = ConstValSpecialRuntime; 16277 } 16278 } 16279 } 16280 16281 if (const_val.special == ConstValSpecialStatic) { 16282 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 16283 ConstExprValue *out_val = &result->value; 16284 // TODO copy_const_val? 16285 *out_val = const_val; 16286 result->value.type = fixed_size_array_type; 16287 for (size_t i = 0; i < elem_count; i += 1) { 16288 ConstExprValue *elem_val = &out_val->data.x_array.data.s_none.elements[i]; 16289 ConstParent *parent = get_const_val_parent(ira->codegen, elem_val); 16290 if (parent != nullptr) { 16291 parent->id = ConstParentIdArray; 16292 parent->data.p_array.array_val = out_val; 16293 parent->data.p_array.elem_index = i; 16294 } 16295 } 16296 return result; 16297 } 16298 16299 if (is_comptime) { 16300 ir_add_error_node(ira, first_non_const_instruction->source_node, 16301 buf_sprintf("unable to evaluate constant expression")); 16302 return ira->codegen->invalid_instruction; 16303 } 16304 16305 IrInstruction *new_instruction = ir_build_container_init_list(&ira->new_irb, 16306 instruction->base.scope, instruction->base.source_node, 16307 container_type_value, elem_count, new_items); 16308 new_instruction->value.type = fixed_size_array_type; 16309 ir_add_alloca(ira, new_instruction, fixed_size_array_type); 16310 return new_instruction; 16311 } else if (container_type->id == ZigTypeIdVoid) { 16312 if (elem_count != 0) { 16313 ir_add_error_node(ira, instruction->base.source_node, 16314 buf_sprintf("void expression expects no arguments")); 16315 return ira->codegen->invalid_instruction; 16316 } 16317 return ir_const_void(ira, &instruction->base); 16318 } else { 16319 ir_add_error_node(ira, instruction->base.source_node, 16320 buf_sprintf("type '%s' does not support array initialization", 16321 buf_ptr(&container_type->name))); 16322 return ira->codegen->invalid_instruction; 16323 } 16324 } else { 16325 ir_add_error(ira, container_type_value, 16326 buf_sprintf("expected type, found '%s' value", buf_ptr(&container_type_value->value.type->name))); 16327 return ira->codegen->invalid_instruction; 16328 } 16329 } 16330 16331 static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira, IrInstructionContainerInitFields *instruction) { 16332 IrInstruction *container_type_value = instruction->container_type->child; 16333 ZigType *container_type = ir_resolve_type(ira, container_type_value); 16334 if (type_is_invalid(container_type)) 16335 return ira->codegen->invalid_instruction; 16336 16337 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 16338 instruction->field_count, instruction->fields); 16339 } 16340 16341 static IrInstruction *ir_analyze_instruction_compile_err(IrAnalyze *ira, 16342 IrInstructionCompileErr *instruction) 16343 { 16344 IrInstruction *msg_value = instruction->msg->child; 16345 Buf *msg_buf = ir_resolve_str(ira, msg_value); 16346 if (!msg_buf) 16347 return ira->codegen->invalid_instruction; 16348 16349 ErrorMsg *msg = ir_add_error(ira, &instruction->base, msg_buf); 16350 size_t i = ira->codegen->tld_ref_source_node_stack.length; 16351 for (;;) { 16352 if (i == 0) 16353 break; 16354 i -= 1; 16355 AstNode *source_node = ira->codegen->tld_ref_source_node_stack.at(i); 16356 if (source_node) { 16357 add_error_note(ira->codegen, msg, source_node, 16358 buf_sprintf("referenced here")); 16359 } 16360 } 16361 16362 return ira->codegen->invalid_instruction; 16363 } 16364 16365 static IrInstruction *ir_analyze_instruction_compile_log(IrAnalyze *ira, IrInstructionCompileLog *instruction) { 16366 Buf buf = BUF_INIT; 16367 fprintf(stderr, "| "); 16368 for (size_t i = 0; i < instruction->msg_count; i += 1) { 16369 IrInstruction *msg = instruction->msg_list[i]->child; 16370 if (type_is_invalid(msg->value.type)) 16371 return ira->codegen->invalid_instruction; 16372 buf_resize(&buf, 0); 16373 render_const_value(ira->codegen, &buf, &msg->value); 16374 const char *comma_str = (i != 0) ? ", " : ""; 16375 fprintf(stderr, "%s%s", comma_str, buf_ptr(&buf)); 16376 } 16377 fprintf(stderr, "\n"); 16378 16379 // Here we bypass higher level functions such as ir_add_error because we do not want 16380 // invalidate_exec to be called. 16381 add_node_error(ira->codegen, instruction->base.source_node, buf_sprintf("found compile log statement")); 16382 16383 return ir_const_void(ira, &instruction->base); 16384 } 16385 16386 static IrInstruction *ir_analyze_instruction_err_name(IrAnalyze *ira, IrInstructionErrName *instruction) { 16387 IrInstruction *value = instruction->value->child; 16388 if (type_is_invalid(value->value.type)) 16389 return ira->codegen->invalid_instruction; 16390 16391 IrInstruction *casted_value = ir_implicit_cast(ira, value, value->value.type); 16392 if (type_is_invalid(casted_value->value.type)) 16393 return ira->codegen->invalid_instruction; 16394 16395 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 16396 true, false, PtrLenUnknown, 0, 0, 0); 16397 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 16398 if (casted_value->value.special == ConstValSpecialStatic) { 16399 ErrorTableEntry *err = casted_value->value.data.x_err_set; 16400 if (!err->cached_error_name_val) { 16401 ConstExprValue *array_val = create_const_str_lit(ira->codegen, &err->name); 16402 err->cached_error_name_val = create_const_slice(ira->codegen, array_val, 0, buf_len(&err->name), true); 16403 } 16404 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 16405 copy_const_val(&result->value, err->cached_error_name_val, true); 16406 result->value.type = str_type; 16407 return result; 16408 } 16409 16410 ira->codegen->generate_error_name_table = true; 16411 16412 IrInstruction *result = ir_build_err_name(&ira->new_irb, 16413 instruction->base.scope, instruction->base.source_node, value); 16414 result->value.type = str_type; 16415 return result; 16416 } 16417 16418 static IrInstruction *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstructionTagName *instruction) { 16419 Error err; 16420 IrInstruction *target = instruction->target->child; 16421 if (type_is_invalid(target->value.type)) 16422 return ira->codegen->invalid_instruction; 16423 16424 assert(target->value.type->id == ZigTypeIdEnum); 16425 16426 if (instr_is_comptime(target)) { 16427 if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusZeroBitsKnown))) 16428 return ira->codegen->invalid_instruction; 16429 TypeEnumField *field = find_enum_field_by_tag(target->value.type, &target->value.data.x_bigint); 16430 ConstExprValue *array_val = create_const_str_lit(ira->codegen, field->name); 16431 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 16432 init_const_slice(ira->codegen, &result->value, array_val, 0, buf_len(field->name), true); 16433 return result; 16434 } 16435 16436 IrInstruction *result = ir_build_tag_name(&ira->new_irb, instruction->base.scope, 16437 instruction->base.source_node, target); 16438 ZigType *u8_ptr_type = get_pointer_to_type_extra( 16439 ira->codegen, ira->codegen->builtin_types.entry_u8, 16440 true, false, PtrLenUnknown, 16441 0, 0, 0); 16442 result->value.type = get_slice_type(ira->codegen, u8_ptr_type); 16443 return result; 16444 } 16445 16446 static IrInstruction *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, 16447 IrInstructionFieldParentPtr *instruction) 16448 { 16449 Error err; 16450 IrInstruction *type_value = instruction->type_value->child; 16451 ZigType *container_type = ir_resolve_type(ira, type_value); 16452 if (type_is_invalid(container_type)) 16453 return ira->codegen->invalid_instruction; 16454 16455 IrInstruction *field_name_value = instruction->field_name->child; 16456 Buf *field_name = ir_resolve_str(ira, field_name_value); 16457 if (!field_name) 16458 return ira->codegen->invalid_instruction; 16459 16460 IrInstruction *field_ptr = instruction->field_ptr->child; 16461 if (type_is_invalid(field_ptr->value.type)) 16462 return ira->codegen->invalid_instruction; 16463 16464 if (container_type->id != ZigTypeIdStruct) { 16465 ir_add_error(ira, type_value, 16466 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 16467 return ira->codegen->invalid_instruction; 16468 } 16469 16470 if ((err = ensure_complete_type(ira->codegen, container_type))) 16471 return ira->codegen->invalid_instruction; 16472 16473 TypeStructField *field = find_struct_type_field(container_type, field_name); 16474 if (field == nullptr) { 16475 ir_add_error(ira, field_name_value, 16476 buf_sprintf("struct '%s' has no field '%s'", 16477 buf_ptr(&container_type->name), buf_ptr(field_name))); 16478 return ira->codegen->invalid_instruction; 16479 } 16480 16481 if (field_ptr->value.type->id != ZigTypeIdPointer) { 16482 ir_add_error(ira, field_ptr, 16483 buf_sprintf("expected pointer, found '%s'", buf_ptr(&field_ptr->value.type->name))); 16484 return ira->codegen->invalid_instruction; 16485 } 16486 16487 bool is_packed = (container_type->data.structure.layout == ContainerLayoutPacked); 16488 uint32_t field_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, field->type_entry); 16489 uint32_t parent_ptr_align = is_packed ? 1 : get_abi_alignment(ira->codegen, container_type); 16490 16491 ZigType *field_ptr_type = get_pointer_to_type_extra(ira->codegen, field->type_entry, 16492 field_ptr->value.type->data.pointer.is_const, 16493 field_ptr->value.type->data.pointer.is_volatile, 16494 PtrLenSingle, 16495 field_ptr_align, 0, 0); 16496 IrInstruction *casted_field_ptr = ir_implicit_cast(ira, field_ptr, field_ptr_type); 16497 if (type_is_invalid(casted_field_ptr->value.type)) 16498 return ira->codegen->invalid_instruction; 16499 16500 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, container_type, 16501 casted_field_ptr->value.type->data.pointer.is_const, 16502 casted_field_ptr->value.type->data.pointer.is_volatile, 16503 PtrLenSingle, 16504 parent_ptr_align, 0, 0); 16505 16506 if (instr_is_comptime(casted_field_ptr)) { 16507 ConstExprValue *field_ptr_val = ir_resolve_const(ira, casted_field_ptr, UndefBad); 16508 if (!field_ptr_val) 16509 return ira->codegen->invalid_instruction; 16510 16511 if (field_ptr_val->data.x_ptr.special != ConstPtrSpecialBaseStruct) { 16512 ir_add_error(ira, field_ptr, buf_sprintf("pointer value not based on parent struct")); 16513 return ira->codegen->invalid_instruction; 16514 } 16515 16516 size_t ptr_field_index = field_ptr_val->data.x_ptr.data.base_struct.field_index; 16517 if (ptr_field_index != field->src_index) { 16518 ir_add_error(ira, &instruction->base, 16519 buf_sprintf("field '%s' has index %" ZIG_PRI_usize " but pointer value is index %" ZIG_PRI_usize " of struct '%s'", 16520 buf_ptr(field->name), field->src_index, 16521 ptr_field_index, buf_ptr(&container_type->name))); 16522 return ira->codegen->invalid_instruction; 16523 } 16524 16525 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 16526 ConstExprValue *out_val = &result->value; 16527 out_val->data.x_ptr.special = ConstPtrSpecialRef; 16528 out_val->data.x_ptr.data.ref.pointee = field_ptr_val->data.x_ptr.data.base_struct.struct_val; 16529 out_val->data.x_ptr.mut = field_ptr_val->data.x_ptr.mut; 16530 return result; 16531 } 16532 16533 IrInstruction *result = ir_build_field_parent_ptr(&ira->new_irb, instruction->base.scope, 16534 instruction->base.source_node, type_value, field_name_value, casted_field_ptr, field); 16535 result->value.type = result_type; 16536 return result; 16537 } 16538 16539 static TypeStructField *validate_byte_offset(IrAnalyze *ira, 16540 IrInstruction *type_value, 16541 IrInstruction *field_name_value, 16542 size_t *byte_offset) 16543 { 16544 ZigType *container_type = ir_resolve_type(ira, type_value); 16545 if (type_is_invalid(container_type)) 16546 return nullptr; 16547 16548 Error err; 16549 if ((err = ensure_complete_type(ira->codegen, container_type))) 16550 return nullptr; 16551 16552 Buf *field_name = ir_resolve_str(ira, field_name_value); 16553 if (!field_name) 16554 return nullptr; 16555 16556 if (container_type->id != ZigTypeIdStruct) { 16557 ir_add_error(ira, type_value, 16558 buf_sprintf("expected struct type, found '%s'", buf_ptr(&container_type->name))); 16559 return nullptr; 16560 } 16561 16562 TypeStructField *field = find_struct_type_field(container_type, field_name); 16563 if (field == nullptr) { 16564 ir_add_error(ira, field_name_value, 16565 buf_sprintf("struct '%s' has no field '%s'", 16566 buf_ptr(&container_type->name), buf_ptr(field_name))); 16567 return nullptr; 16568 } 16569 16570 if (!type_has_bits(field->type_entry)) { 16571 ir_add_error(ira, field_name_value, 16572 buf_sprintf("zero-bit field '%s' in struct '%s' has no offset", 16573 buf_ptr(field_name), buf_ptr(&container_type->name))); 16574 return nullptr; 16575 } 16576 16577 *byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, container_type->type_ref, field->gen_index); 16578 return field; 16579 } 16580 16581 static IrInstruction *ir_analyze_instruction_byte_offset_of(IrAnalyze *ira, 16582 IrInstructionByteOffsetOf *instruction) 16583 { 16584 IrInstruction *type_value = instruction->type_value->child; 16585 if (type_is_invalid(type_value->value.type)) 16586 return ira->codegen->invalid_instruction; 16587 16588 IrInstruction *field_name_value = instruction->field_name->child; 16589 size_t byte_offset = 0; 16590 if (!validate_byte_offset(ira, type_value, field_name_value, &byte_offset)) 16591 return ira->codegen->invalid_instruction; 16592 16593 16594 return ir_const_unsigned(ira, &instruction->base, byte_offset); 16595 } 16596 16597 static IrInstruction *ir_analyze_instruction_bit_offset_of(IrAnalyze *ira, 16598 IrInstructionBitOffsetOf *instruction) 16599 { 16600 IrInstruction *type_value = instruction->type_value->child; 16601 if (type_is_invalid(type_value->value.type)) 16602 return ira->codegen->invalid_instruction; 16603 IrInstruction *field_name_value = instruction->field_name->child; 16604 size_t byte_offset = 0; 16605 TypeStructField *field = nullptr; 16606 if (!(field = validate_byte_offset(ira, type_value, field_name_value, &byte_offset))) 16607 return ira->codegen->invalid_instruction; 16608 16609 size_t bit_offset = byte_offset * 8 + field->bit_offset_in_host; 16610 return ir_const_unsigned(ira, &instruction->base, bit_offset); 16611 } 16612 16613 static void ensure_field_index(ZigType *type, const char *field_name, size_t index) { 16614 Buf *field_name_buf; 16615 16616 assert(type != nullptr && !type_is_invalid(type)); 16617 // Check for our field by creating a buffer in place then using the comma operator to free it so that we don't 16618 // leak memory in debug mode. 16619 assert(find_struct_type_field(type, field_name_buf = buf_create_from_str(field_name))->src_index == index && 16620 (buf_deinit(field_name_buf), true)); 16621 } 16622 16623 static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, ZigType *root) { 16624 Error err; 16625 static ConstExprValue *type_info_var = nullptr; // TODO oops this global variable made it past code review 16626 static ZigType *type_info_type = nullptr; // TODO oops this global variable made it past code review 16627 if (type_info_var == nullptr) { 16628 type_info_var = get_builtin_value(ira->codegen, "TypeInfo"); 16629 assert(type_info_var->type->id == ZigTypeIdMetaType); 16630 16631 assertNoError(ensure_complete_type(ira->codegen, type_info_var->data.x_type)); 16632 type_info_type = type_info_var->data.x_type; 16633 assert(type_info_type->id == ZigTypeIdUnion); 16634 } 16635 16636 if (type_name == nullptr && root == nullptr) 16637 return type_info_type; 16638 else if (type_name == nullptr) 16639 return root; 16640 16641 ZigType *root_type = (root == nullptr) ? type_info_type : root; 16642 16643 ScopeDecls *type_info_scope = get_container_scope(root_type); 16644 assert(type_info_scope != nullptr); 16645 16646 Buf field_name = BUF_INIT; 16647 buf_init_from_str(&field_name, type_name); 16648 auto entry = type_info_scope->decl_table.get(&field_name); 16649 buf_deinit(&field_name); 16650 16651 TldVar *tld = (TldVar *)entry; 16652 assert(tld->base.id == TldIdVar); 16653 16654 ZigVar *var = tld->var; 16655 16656 if ((err = ensure_complete_type(ira->codegen, var->value->type))) 16657 return ira->codegen->builtin_types.entry_invalid; 16658 assert(var->value->type->id == ZigTypeIdMetaType); 16659 return var->value->data.x_type; 16660 } 16661 16662 static Error ir_make_type_info_defs(IrAnalyze *ira, ConstExprValue *out_val, ScopeDecls *decls_scope) { 16663 Error err; 16664 ZigType *type_info_definition_type = ir_type_info_get_type(ira, "Definition", nullptr); 16665 if ((err = ensure_complete_type(ira->codegen, type_info_definition_type))) 16666 return err; 16667 16668 ensure_field_index(type_info_definition_type, "name", 0); 16669 ensure_field_index(type_info_definition_type, "is_pub", 1); 16670 ensure_field_index(type_info_definition_type, "data", 2); 16671 16672 ZigType *type_info_definition_data_type = ir_type_info_get_type(ira, "Data", type_info_definition_type); 16673 if ((err = ensure_complete_type(ira->codegen, type_info_definition_data_type))) 16674 return err; 16675 16676 ZigType *type_info_fn_def_type = ir_type_info_get_type(ira, "FnDef", type_info_definition_data_type); 16677 if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_type))) 16678 return err; 16679 16680 ZigType *type_info_fn_def_inline_type = ir_type_info_get_type(ira, "Inline", type_info_fn_def_type); 16681 if ((err = ensure_complete_type(ira->codegen, type_info_fn_def_inline_type))) 16682 return err; 16683 16684 // Loop through our definitions once to figure out how many definitions we will generate info for. 16685 auto decl_it = decls_scope->decl_table.entry_iterator(); 16686 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr; 16687 int definition_count = 0; 16688 16689 while ((curr_entry = decl_it.next()) != nullptr) { 16690 // If the definition is unresolved, force it to be resolved again. 16691 if (curr_entry->value->resolution == TldResolutionUnresolved) { 16692 resolve_top_level_decl(ira->codegen, curr_entry->value, false, curr_entry->value->source_node); 16693 if (curr_entry->value->resolution != TldResolutionOk) { 16694 return ErrorSemanticAnalyzeFail; 16695 } 16696 } 16697 16698 // Skip comptime blocks and test functions. 16699 if (curr_entry->value->id != TldIdCompTime) { 16700 if (curr_entry->value->id == TldIdFn) { 16701 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 16702 if (fn_entry->is_test) 16703 continue; 16704 } 16705 16706 definition_count += 1; 16707 } 16708 } 16709 16710 ConstExprValue *definition_array = create_const_vals(1); 16711 definition_array->special = ConstValSpecialStatic; 16712 definition_array->type = get_array_type(ira->codegen, type_info_definition_type, definition_count); 16713 definition_array->data.x_array.special = ConstArraySpecialNone; 16714 definition_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; 16715 definition_array->data.x_array.data.s_none.elements = create_const_vals(definition_count); 16716 init_const_slice(ira->codegen, out_val, definition_array, 0, definition_count, false); 16717 16718 // Loop through the definitions and generate info. 16719 decl_it = decls_scope->decl_table.entry_iterator(); 16720 curr_entry = nullptr; 16721 int definition_index = 0; 16722 while ((curr_entry = decl_it.next()) != nullptr) { 16723 // Skip comptime blocks and test functions. 16724 if (curr_entry->value->id == TldIdCompTime) { 16725 continue; 16726 } else if (curr_entry->value->id == TldIdFn) { 16727 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 16728 if (fn_entry->is_test) 16729 continue; 16730 } 16731 16732 ConstExprValue *definition_val = &definition_array->data.x_array.data.s_none.elements[definition_index]; 16733 16734 definition_val->special = ConstValSpecialStatic; 16735 definition_val->type = type_info_definition_type; 16736 16737 ConstExprValue *inner_fields = create_const_vals(3); 16738 ConstExprValue *name = create_const_str_lit(ira->codegen, curr_entry->key); 16739 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(curr_entry->key), true); 16740 inner_fields[1].special = ConstValSpecialStatic; 16741 inner_fields[1].type = ira->codegen->builtin_types.entry_bool; 16742 inner_fields[1].data.x_bool = curr_entry->value->visib_mod == VisibModPub; 16743 inner_fields[2].special = ConstValSpecialStatic; 16744 inner_fields[2].type = type_info_definition_data_type; 16745 inner_fields[2].data.x_union.parent.id = ConstParentIdStruct; 16746 inner_fields[2].data.x_union.parent.data.p_struct.struct_val = definition_val; 16747 inner_fields[2].data.x_union.parent.data.p_struct.field_index = 1; 16748 16749 switch (curr_entry->value->id) { 16750 case TldIdVar: 16751 { 16752 ZigVar *var = ((TldVar *)curr_entry->value)->var; 16753 if ((err = ensure_complete_type(ira->codegen, var->value->type))) 16754 return ErrorSemanticAnalyzeFail; 16755 16756 if (var->value->type->id == ZigTypeIdMetaType) 16757 { 16758 // We have a variable of type 'type', so it's actually a type definition. 16759 // 0: Data.Type: type 16760 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); 16761 inner_fields[2].data.x_union.payload = var->value; 16762 } 16763 else 16764 { 16765 // We have a variable of another type, so we store the type of the variable. 16766 // 1: Data.Var: type 16767 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 1); 16768 16769 ConstExprValue *payload = create_const_vals(1); 16770 payload->type = ira->codegen->builtin_types.entry_type; 16771 payload->data.x_type = var->value->type; 16772 16773 inner_fields[2].data.x_union.payload = payload; 16774 } 16775 16776 break; 16777 } 16778 case TldIdFn: 16779 { 16780 // 2: Data.Fn: Data.FnDef 16781 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 2); 16782 16783 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry; 16784 assert(!fn_entry->is_test); 16785 16786 AstNodeFnProto *fn_node = (AstNodeFnProto *)(fn_entry->proto_node); 16787 16788 ConstExprValue *fn_def_val = create_const_vals(1); 16789 fn_def_val->special = ConstValSpecialStatic; 16790 fn_def_val->type = type_info_fn_def_type; 16791 fn_def_val->data.x_struct.parent.id = ConstParentIdUnion; 16792 fn_def_val->data.x_struct.parent.data.p_union.union_val = &inner_fields[2]; 16793 16794 ConstExprValue *fn_def_fields = create_const_vals(9); 16795 fn_def_val->data.x_struct.fields = fn_def_fields; 16796 16797 // fn_type: type 16798 ensure_field_index(fn_def_val->type, "fn_type", 0); 16799 fn_def_fields[0].special = ConstValSpecialStatic; 16800 fn_def_fields[0].type = ira->codegen->builtin_types.entry_type; 16801 fn_def_fields[0].data.x_type = fn_entry->type_entry; 16802 // inline_type: Data.FnDef.Inline 16803 ensure_field_index(fn_def_val->type, "inline_type", 1); 16804 fn_def_fields[1].special = ConstValSpecialStatic; 16805 fn_def_fields[1].type = type_info_fn_def_inline_type; 16806 bigint_init_unsigned(&fn_def_fields[1].data.x_enum_tag, fn_entry->fn_inline); 16807 // calling_convention: TypeInfo.CallingConvention 16808 ensure_field_index(fn_def_val->type, "calling_convention", 2); 16809 fn_def_fields[2].special = ConstValSpecialStatic; 16810 fn_def_fields[2].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); 16811 bigint_init_unsigned(&fn_def_fields[2].data.x_enum_tag, fn_node->cc); 16812 // is_var_args: bool 16813 ensure_field_index(fn_def_val->type, "is_var_args", 3); 16814 bool is_varargs = fn_node->is_var_args; 16815 fn_def_fields[3].special = ConstValSpecialStatic; 16816 fn_def_fields[3].type = ira->codegen->builtin_types.entry_bool; 16817 fn_def_fields[3].data.x_bool = is_varargs; 16818 // is_extern: bool 16819 ensure_field_index(fn_def_val->type, "is_extern", 4); 16820 fn_def_fields[4].special = ConstValSpecialStatic; 16821 fn_def_fields[4].type = ira->codegen->builtin_types.entry_bool; 16822 fn_def_fields[4].data.x_bool = fn_node->is_extern; 16823 // is_export: bool 16824 ensure_field_index(fn_def_val->type, "is_export", 5); 16825 fn_def_fields[5].special = ConstValSpecialStatic; 16826 fn_def_fields[5].type = ira->codegen->builtin_types.entry_bool; 16827 fn_def_fields[5].data.x_bool = fn_node->is_export; 16828 // lib_name: ?[]const u8 16829 ensure_field_index(fn_def_val->type, "lib_name", 6); 16830 fn_def_fields[6].special = ConstValSpecialStatic; 16831 ZigType *u8_ptr = get_pointer_to_type_extra( 16832 ira->codegen, ira->codegen->builtin_types.entry_u8, 16833 true, false, PtrLenUnknown, 16834 0, 0, 0); 16835 fn_def_fields[6].type = get_optional_type(ira->codegen, get_slice_type(ira->codegen, u8_ptr)); 16836 if (fn_node->is_extern && buf_len(fn_node->lib_name) > 0) { 16837 fn_def_fields[6].data.x_optional = create_const_vals(1); 16838 ConstExprValue *lib_name = create_const_str_lit(ira->codegen, fn_node->lib_name); 16839 init_const_slice(ira->codegen, fn_def_fields[6].data.x_optional, lib_name, 0, buf_len(fn_node->lib_name), true); 16840 } else { 16841 fn_def_fields[6].data.x_optional = nullptr; 16842 } 16843 // return_type: type 16844 ensure_field_index(fn_def_val->type, "return_type", 7); 16845 fn_def_fields[7].special = ConstValSpecialStatic; 16846 fn_def_fields[7].type = ira->codegen->builtin_types.entry_type; 16847 if (fn_entry->src_implicit_return_type != nullptr) 16848 fn_def_fields[7].data.x_type = fn_entry->src_implicit_return_type; 16849 else if (fn_entry->type_entry->data.fn.gen_return_type != nullptr) 16850 fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.gen_return_type; 16851 else 16852 fn_def_fields[7].data.x_type = fn_entry->type_entry->data.fn.fn_type_id.return_type; 16853 // arg_names: [][] const u8 16854 ensure_field_index(fn_def_val->type, "arg_names", 8); 16855 size_t fn_arg_count = fn_entry->variable_list.length; 16856 ConstExprValue *fn_arg_name_array = create_const_vals(1); 16857 fn_arg_name_array->special = ConstValSpecialStatic; 16858 fn_arg_name_array->type = get_array_type(ira->codegen, 16859 get_slice_type(ira->codegen, u8_ptr), fn_arg_count); 16860 fn_arg_name_array->data.x_array.special = ConstArraySpecialNone; 16861 fn_arg_name_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; 16862 fn_arg_name_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); 16863 16864 init_const_slice(ira->codegen, &fn_def_fields[8], fn_arg_name_array, 0, fn_arg_count, false); 16865 16866 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) 16867 { 16868 ZigVar *arg_var = fn_entry->variable_list.at(fn_arg_index); 16869 ConstExprValue *fn_arg_name_val = &fn_arg_name_array->data.x_array.data.s_none.elements[fn_arg_index]; 16870 ConstExprValue *arg_name = create_const_str_lit(ira->codegen, &arg_var->name); 16871 init_const_slice(ira->codegen, fn_arg_name_val, arg_name, 0, buf_len(&arg_var->name), true); 16872 fn_arg_name_val->data.x_struct.parent.id = ConstParentIdArray; 16873 fn_arg_name_val->data.x_struct.parent.data.p_array.array_val = fn_arg_name_array; 16874 fn_arg_name_val->data.x_struct.parent.data.p_array.elem_index = fn_arg_index; 16875 } 16876 16877 inner_fields[2].data.x_union.payload = fn_def_val; 16878 break; 16879 } 16880 case TldIdContainer: 16881 { 16882 ZigType *type_entry = ((TldContainer *)curr_entry->value)->type_entry; 16883 if ((err = ensure_complete_type(ira->codegen, type_entry))) 16884 return ErrorSemanticAnalyzeFail; 16885 16886 // This is a type. 16887 bigint_init_unsigned(&inner_fields[2].data.x_union.tag, 0); 16888 16889 ConstExprValue *payload = create_const_vals(1); 16890 payload->type = ira->codegen->builtin_types.entry_type; 16891 payload->data.x_type = type_entry; 16892 16893 inner_fields[2].data.x_union.payload = payload; 16894 16895 break; 16896 } 16897 default: 16898 zig_unreachable(); 16899 } 16900 16901 definition_val->data.x_struct.fields = inner_fields; 16902 definition_index++; 16903 } 16904 16905 assert(definition_index == definition_count); 16906 return ErrorNone; 16907 } 16908 16909 static ConstExprValue *create_ptr_like_type_info(IrAnalyze *ira, ZigType *ptr_type_entry) { 16910 Error err; 16911 ZigType *attrs_type; 16912 uint32_t size_enum_index; 16913 if (is_slice(ptr_type_entry)) { 16914 attrs_type = ptr_type_entry->data.structure.fields[slice_ptr_index].type_entry; 16915 size_enum_index = 2; 16916 } else if (ptr_type_entry->id == ZigTypeIdPointer) { 16917 attrs_type = ptr_type_entry; 16918 size_enum_index = (ptr_type_entry->data.pointer.ptr_len == PtrLenSingle) ? 0 : 1; 16919 } else { 16920 zig_unreachable(); 16921 } 16922 16923 if ((err = type_resolve(ira->codegen, attrs_type->data.pointer.child_type, ResolveStatusAlignmentKnown))) 16924 return nullptr; 16925 16926 ZigType *type_info_pointer_type = ir_type_info_get_type(ira, "Pointer", nullptr); 16927 assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_type)); 16928 16929 ConstExprValue *result = create_const_vals(1); 16930 result->special = ConstValSpecialStatic; 16931 result->type = type_info_pointer_type; 16932 16933 ConstExprValue *fields = create_const_vals(5); 16934 result->data.x_struct.fields = fields; 16935 16936 // size: Size 16937 ensure_field_index(result->type, "size", 0); 16938 ZigType *type_info_pointer_size_type = ir_type_info_get_type(ira, "Size", type_info_pointer_type); 16939 assertNoError(ensure_complete_type(ira->codegen, type_info_pointer_size_type)); 16940 fields[0].special = ConstValSpecialStatic; 16941 fields[0].type = type_info_pointer_size_type; 16942 bigint_init_unsigned(&fields[0].data.x_enum_tag, size_enum_index); 16943 16944 // is_const: bool 16945 ensure_field_index(result->type, "is_const", 1); 16946 fields[1].special = ConstValSpecialStatic; 16947 fields[1].type = ira->codegen->builtin_types.entry_bool; 16948 fields[1].data.x_bool = attrs_type->data.pointer.is_const; 16949 // is_volatile: bool 16950 ensure_field_index(result->type, "is_volatile", 2); 16951 fields[2].special = ConstValSpecialStatic; 16952 fields[2].type = ira->codegen->builtin_types.entry_bool; 16953 fields[2].data.x_bool = attrs_type->data.pointer.is_volatile; 16954 // alignment: u32 16955 ensure_field_index(result->type, "alignment", 3); 16956 fields[3].special = ConstValSpecialStatic; 16957 fields[3].type = get_int_type(ira->codegen, false, 29); 16958 bigint_init_unsigned(&fields[3].data.x_bigint, get_ptr_align(ira->codegen, attrs_type)); 16959 // child: type 16960 ensure_field_index(result->type, "child", 4); 16961 fields[4].special = ConstValSpecialStatic; 16962 fields[4].type = ira->codegen->builtin_types.entry_type; 16963 fields[4].data.x_type = attrs_type->data.pointer.child_type; 16964 16965 return result; 16966 }; 16967 16968 static void make_enum_field_val(IrAnalyze *ira, ConstExprValue *enum_field_val, TypeEnumField *enum_field, 16969 ZigType *type_info_enum_field_type) 16970 { 16971 enum_field_val->special = ConstValSpecialStatic; 16972 enum_field_val->type = type_info_enum_field_type; 16973 16974 ConstExprValue *inner_fields = create_const_vals(2); 16975 inner_fields[1].special = ConstValSpecialStatic; 16976 inner_fields[1].type = ira->codegen->builtin_types.entry_usize; 16977 16978 ConstExprValue *name = create_const_str_lit(ira->codegen, enum_field->name); 16979 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(enum_field->name), true); 16980 16981 bigint_init_bigint(&inner_fields[1].data.x_bigint, &enum_field->value); 16982 16983 enum_field_val->data.x_struct.fields = inner_fields; 16984 } 16985 16986 static Error ir_make_type_info_value(IrAnalyze *ira, ZigType *type_entry, ConstExprValue **out) { 16987 Error err; 16988 assert(type_entry != nullptr); 16989 assert(!type_is_invalid(type_entry)); 16990 16991 if ((err = ensure_complete_type(ira->codegen, type_entry))) 16992 return err; 16993 16994 if (type_entry == ira->codegen->builtin_types.entry_global_error_set) { 16995 zig_panic("TODO implement @typeInfo for global error set"); 16996 } 16997 16998 ConstExprValue *result = nullptr; 16999 switch (type_entry->id) 17000 { 17001 case ZigTypeIdInvalid: 17002 zig_unreachable(); 17003 case ZigTypeIdMetaType: 17004 case ZigTypeIdVoid: 17005 case ZigTypeIdBool: 17006 case ZigTypeIdUnreachable: 17007 case ZigTypeIdComptimeFloat: 17008 case ZigTypeIdComptimeInt: 17009 case ZigTypeIdUndefined: 17010 case ZigTypeIdNull: 17011 case ZigTypeIdNamespace: 17012 case ZigTypeIdArgTuple: 17013 case ZigTypeIdOpaque: 17014 *out = nullptr; 17015 return ErrorNone; 17016 default: 17017 { 17018 // Lookup an available value in our cache. 17019 auto entry = ira->codegen->type_info_cache.maybe_get(type_entry); 17020 if (entry != nullptr) { 17021 *out = entry->value; 17022 return ErrorNone; 17023 } 17024 17025 // Fallthrough if we don't find one. 17026 } 17027 case ZigTypeIdInt: 17028 { 17029 result = create_const_vals(1); 17030 result->special = ConstValSpecialStatic; 17031 result->type = ir_type_info_get_type(ira, "Int", nullptr); 17032 17033 ConstExprValue *fields = create_const_vals(2); 17034 result->data.x_struct.fields = fields; 17035 17036 // is_signed: bool 17037 ensure_field_index(result->type, "is_signed", 0); 17038 fields[0].special = ConstValSpecialStatic; 17039 fields[0].type = ira->codegen->builtin_types.entry_bool; 17040 fields[0].data.x_bool = type_entry->data.integral.is_signed; 17041 // bits: u8 17042 ensure_field_index(result->type, "bits", 1); 17043 fields[1].special = ConstValSpecialStatic; 17044 fields[1].type = ira->codegen->builtin_types.entry_u8; 17045 bigint_init_unsigned(&fields[1].data.x_bigint, type_entry->data.integral.bit_count); 17046 17047 break; 17048 } 17049 case ZigTypeIdFloat: 17050 { 17051 result = create_const_vals(1); 17052 result->special = ConstValSpecialStatic; 17053 result->type = ir_type_info_get_type(ira, "Float", nullptr); 17054 17055 ConstExprValue *fields = create_const_vals(1); 17056 result->data.x_struct.fields = fields; 17057 17058 // bits: u8 17059 ensure_field_index(result->type, "bits", 0); 17060 fields[0].special = ConstValSpecialStatic; 17061 fields[0].type = ira->codegen->builtin_types.entry_u8; 17062 bigint_init_unsigned(&fields->data.x_bigint, type_entry->data.floating.bit_count); 17063 17064 break; 17065 } 17066 case ZigTypeIdPointer: 17067 { 17068 result = create_ptr_like_type_info(ira, type_entry); 17069 if (result == nullptr) 17070 return ErrorSemanticAnalyzeFail; 17071 break; 17072 } 17073 case ZigTypeIdArray: 17074 { 17075 result = create_const_vals(1); 17076 result->special = ConstValSpecialStatic; 17077 result->type = ir_type_info_get_type(ira, "Array", nullptr); 17078 17079 ConstExprValue *fields = create_const_vals(2); 17080 result->data.x_struct.fields = fields; 17081 17082 // len: usize 17083 ensure_field_index(result->type, "len", 0); 17084 fields[0].special = ConstValSpecialStatic; 17085 fields[0].type = ira->codegen->builtin_types.entry_usize; 17086 bigint_init_unsigned(&fields[0].data.x_bigint, type_entry->data.array.len); 17087 // child: type 17088 ensure_field_index(result->type, "child", 1); 17089 fields[1].special = ConstValSpecialStatic; 17090 fields[1].type = ira->codegen->builtin_types.entry_type; 17091 fields[1].data.x_type = type_entry->data.array.child_type; 17092 17093 break; 17094 } 17095 case ZigTypeIdOptional: 17096 { 17097 result = create_const_vals(1); 17098 result->special = ConstValSpecialStatic; 17099 result->type = ir_type_info_get_type(ira, "Optional", nullptr); 17100 17101 ConstExprValue *fields = create_const_vals(1); 17102 result->data.x_struct.fields = fields; 17103 17104 // child: type 17105 ensure_field_index(result->type, "child", 0); 17106 fields[0].special = ConstValSpecialStatic; 17107 fields[0].type = ira->codegen->builtin_types.entry_type; 17108 fields[0].data.x_type = type_entry->data.maybe.child_type; 17109 17110 break; 17111 } 17112 case ZigTypeIdPromise: 17113 { 17114 result = create_const_vals(1); 17115 result->special = ConstValSpecialStatic; 17116 result->type = ir_type_info_get_type(ira, "Promise", nullptr); 17117 17118 ConstExprValue *fields = create_const_vals(1); 17119 result->data.x_struct.fields = fields; 17120 17121 // child: ?type 17122 ensure_field_index(result->type, "child", 0); 17123 fields[0].special = ConstValSpecialStatic; 17124 fields[0].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 17125 17126 if (type_entry->data.promise.result_type == nullptr) 17127 fields[0].data.x_optional = nullptr; 17128 else { 17129 ConstExprValue *child_type = create_const_vals(1); 17130 child_type->special = ConstValSpecialStatic; 17131 child_type->type = ira->codegen->builtin_types.entry_type; 17132 child_type->data.x_type = type_entry->data.promise.result_type; 17133 fields[0].data.x_optional = child_type; 17134 } 17135 17136 break; 17137 } 17138 case ZigTypeIdEnum: 17139 { 17140 result = create_const_vals(1); 17141 result->special = ConstValSpecialStatic; 17142 result->type = ir_type_info_get_type(ira, "Enum", nullptr); 17143 17144 ConstExprValue *fields = create_const_vals(4); 17145 result->data.x_struct.fields = fields; 17146 17147 // layout: ContainerLayout 17148 ensure_field_index(result->type, "layout", 0); 17149 fields[0].special = ConstValSpecialStatic; 17150 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 17151 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.enumeration.layout); 17152 // tag_type: type 17153 ensure_field_index(result->type, "tag_type", 1); 17154 fields[1].special = ConstValSpecialStatic; 17155 fields[1].type = ira->codegen->builtin_types.entry_type; 17156 fields[1].data.x_type = type_entry->data.enumeration.tag_int_type; 17157 // fields: []TypeInfo.EnumField 17158 ensure_field_index(result->type, "fields", 2); 17159 17160 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 17161 uint32_t enum_field_count = type_entry->data.enumeration.src_field_count; 17162 17163 ConstExprValue *enum_field_array = create_const_vals(1); 17164 enum_field_array->special = ConstValSpecialStatic; 17165 enum_field_array->type = get_array_type(ira->codegen, type_info_enum_field_type, enum_field_count); 17166 enum_field_array->data.x_array.special = ConstArraySpecialNone; 17167 enum_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; 17168 enum_field_array->data.x_array.data.s_none.elements = create_const_vals(enum_field_count); 17169 17170 init_const_slice(ira->codegen, &fields[2], enum_field_array, 0, enum_field_count, false); 17171 17172 for (uint32_t enum_field_index = 0; enum_field_index < enum_field_count; enum_field_index++) 17173 { 17174 TypeEnumField *enum_field = &type_entry->data.enumeration.fields[enum_field_index]; 17175 ConstExprValue *enum_field_val = &enum_field_array->data.x_array.data.s_none.elements[enum_field_index]; 17176 make_enum_field_val(ira, enum_field_val, enum_field, type_info_enum_field_type); 17177 enum_field_val->data.x_struct.parent.id = ConstParentIdArray; 17178 enum_field_val->data.x_struct.parent.data.p_array.array_val = enum_field_array; 17179 enum_field_val->data.x_struct.parent.data.p_array.elem_index = enum_field_index; 17180 } 17181 // defs: []TypeInfo.Definition 17182 ensure_field_index(result->type, "defs", 3); 17183 if ((err = ir_make_type_info_defs(ira, &fields[3], type_entry->data.enumeration.decls_scope))) 17184 return err; 17185 17186 break; 17187 } 17188 case ZigTypeIdErrorSet: 17189 { 17190 result = create_const_vals(1); 17191 result->special = ConstValSpecialStatic; 17192 result->type = ir_type_info_get_type(ira, "ErrorSet", nullptr); 17193 17194 ConstExprValue *fields = create_const_vals(1); 17195 result->data.x_struct.fields = fields; 17196 17197 // errors: []TypeInfo.Error 17198 ensure_field_index(result->type, "errors", 0); 17199 17200 ZigType *type_info_error_type = ir_type_info_get_type(ira, "Error", nullptr); 17201 uint32_t error_count = type_entry->data.error_set.err_count; 17202 ConstExprValue *error_array = create_const_vals(1); 17203 error_array->special = ConstValSpecialStatic; 17204 error_array->type = get_array_type(ira->codegen, type_info_error_type, error_count); 17205 error_array->data.x_array.special = ConstArraySpecialNone; 17206 error_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; 17207 error_array->data.x_array.data.s_none.elements = create_const_vals(error_count); 17208 17209 init_const_slice(ira->codegen, &fields[0], error_array, 0, error_count, false); 17210 for (uint32_t error_index = 0; error_index < error_count; error_index++) { 17211 ErrorTableEntry *error = type_entry->data.error_set.errors[error_index]; 17212 ConstExprValue *error_val = &error_array->data.x_array.data.s_none.elements[error_index]; 17213 17214 error_val->special = ConstValSpecialStatic; 17215 error_val->type = type_info_error_type; 17216 17217 ConstExprValue *inner_fields = create_const_vals(2); 17218 inner_fields[1].special = ConstValSpecialStatic; 17219 inner_fields[1].type = ira->codegen->builtin_types.entry_usize; 17220 17221 ConstExprValue *name = nullptr; 17222 if (error->cached_error_name_val != nullptr) 17223 name = error->cached_error_name_val; 17224 if (name == nullptr) 17225 name = create_const_str_lit(ira->codegen, &error->name); 17226 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(&error->name), true); 17227 bigint_init_unsigned(&inner_fields[1].data.x_bigint, error->value); 17228 17229 error_val->data.x_struct.fields = inner_fields; 17230 error_val->data.x_struct.parent.id = ConstParentIdArray; 17231 error_val->data.x_struct.parent.data.p_array.array_val = error_array; 17232 error_val->data.x_struct.parent.data.p_array.elem_index = error_index; 17233 } 17234 17235 break; 17236 } 17237 case ZigTypeIdErrorUnion: 17238 { 17239 result = create_const_vals(1); 17240 result->special = ConstValSpecialStatic; 17241 result->type = ir_type_info_get_type(ira, "ErrorUnion", nullptr); 17242 17243 ConstExprValue *fields = create_const_vals(2); 17244 result->data.x_struct.fields = fields; 17245 17246 // error_set: type 17247 ensure_field_index(result->type, "error_set", 0); 17248 fields[0].special = ConstValSpecialStatic; 17249 fields[0].type = ira->codegen->builtin_types.entry_type; 17250 fields[0].data.x_type = type_entry->data.error_union.err_set_type; 17251 17252 // payload: type 17253 ensure_field_index(result->type, "payload", 1); 17254 fields[1].special = ConstValSpecialStatic; 17255 fields[1].type = ira->codegen->builtin_types.entry_type; 17256 fields[1].data.x_type = type_entry->data.error_union.payload_type; 17257 17258 break; 17259 } 17260 case ZigTypeIdUnion: 17261 { 17262 result = create_const_vals(1); 17263 result->special = ConstValSpecialStatic; 17264 result->type = ir_type_info_get_type(ira, "Union", nullptr); 17265 17266 ConstExprValue *fields = create_const_vals(4); 17267 result->data.x_struct.fields = fields; 17268 17269 // layout: ContainerLayout 17270 ensure_field_index(result->type, "layout", 0); 17271 fields[0].special = ConstValSpecialStatic; 17272 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 17273 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.unionation.layout); 17274 // tag_type: ?type 17275 ensure_field_index(result->type, "tag_type", 1); 17276 fields[1].special = ConstValSpecialStatic; 17277 fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 17278 17279 AstNode *union_decl_node = type_entry->data.unionation.decl_node; 17280 if (union_decl_node->data.container_decl.auto_enum || 17281 union_decl_node->data.container_decl.init_arg_expr != nullptr) 17282 { 17283 ConstExprValue *tag_type = create_const_vals(1); 17284 tag_type->special = ConstValSpecialStatic; 17285 tag_type->type = ira->codegen->builtin_types.entry_type; 17286 tag_type->data.x_type = type_entry->data.unionation.tag_type; 17287 fields[1].data.x_optional = tag_type; 17288 } else { 17289 fields[1].data.x_optional = nullptr; 17290 } 17291 // fields: []TypeInfo.UnionField 17292 ensure_field_index(result->type, "fields", 2); 17293 17294 ZigType *type_info_union_field_type = ir_type_info_get_type(ira, "UnionField", nullptr); 17295 uint32_t union_field_count = type_entry->data.unionation.src_field_count; 17296 17297 ConstExprValue *union_field_array = create_const_vals(1); 17298 union_field_array->special = ConstValSpecialStatic; 17299 union_field_array->type = get_array_type(ira->codegen, type_info_union_field_type, union_field_count); 17300 union_field_array->data.x_array.special = ConstArraySpecialNone; 17301 union_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; 17302 union_field_array->data.x_array.data.s_none.elements = create_const_vals(union_field_count); 17303 17304 init_const_slice(ira->codegen, &fields[2], union_field_array, 0, union_field_count, false); 17305 17306 ZigType *type_info_enum_field_type = ir_type_info_get_type(ira, "EnumField", nullptr); 17307 17308 for (uint32_t union_field_index = 0; union_field_index < union_field_count; union_field_index++) { 17309 TypeUnionField *union_field = &type_entry->data.unionation.fields[union_field_index]; 17310 ConstExprValue *union_field_val = &union_field_array->data.x_array.data.s_none.elements[union_field_index]; 17311 17312 union_field_val->special = ConstValSpecialStatic; 17313 union_field_val->type = type_info_union_field_type; 17314 17315 ConstExprValue *inner_fields = create_const_vals(3); 17316 inner_fields[1].special = ConstValSpecialStatic; 17317 inner_fields[1].type = get_optional_type(ira->codegen, type_info_enum_field_type); 17318 17319 if (fields[1].data.x_optional == nullptr) { 17320 inner_fields[1].data.x_optional = nullptr; 17321 } else { 17322 inner_fields[1].data.x_optional = create_const_vals(1); 17323 make_enum_field_val(ira, inner_fields[1].data.x_optional, union_field->enum_field, type_info_enum_field_type); 17324 } 17325 17326 inner_fields[2].special = ConstValSpecialStatic; 17327 inner_fields[2].type = ira->codegen->builtin_types.entry_type; 17328 inner_fields[2].data.x_type = union_field->type_entry; 17329 17330 ConstExprValue *name = create_const_str_lit(ira->codegen, union_field->name); 17331 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(union_field->name), true); 17332 17333 union_field_val->data.x_struct.fields = inner_fields; 17334 union_field_val->data.x_struct.parent.id = ConstParentIdArray; 17335 union_field_val->data.x_struct.parent.data.p_array.array_val = union_field_array; 17336 union_field_val->data.x_struct.parent.data.p_array.elem_index = union_field_index; 17337 } 17338 // defs: []TypeInfo.Definition 17339 ensure_field_index(result->type, "defs", 3); 17340 if ((err = ir_make_type_info_defs(ira, &fields[3], type_entry->data.unionation.decls_scope))) 17341 return err; 17342 17343 break; 17344 } 17345 case ZigTypeIdStruct: 17346 { 17347 if (type_entry->data.structure.is_slice) { 17348 result = create_ptr_like_type_info(ira, type_entry); 17349 if (result == nullptr) 17350 return ErrorSemanticAnalyzeFail; 17351 break; 17352 } 17353 17354 result = create_const_vals(1); 17355 result->special = ConstValSpecialStatic; 17356 result->type = ir_type_info_get_type(ira, "Struct", nullptr); 17357 17358 ConstExprValue *fields = create_const_vals(3); 17359 result->data.x_struct.fields = fields; 17360 17361 // layout: ContainerLayout 17362 ensure_field_index(result->type, "layout", 0); 17363 fields[0].special = ConstValSpecialStatic; 17364 fields[0].type = ir_type_info_get_type(ira, "ContainerLayout", nullptr); 17365 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.structure.layout); 17366 // fields: []TypeInfo.StructField 17367 ensure_field_index(result->type, "fields", 1); 17368 17369 ZigType *type_info_struct_field_type = ir_type_info_get_type(ira, "StructField", nullptr); 17370 uint32_t struct_field_count = type_entry->data.structure.src_field_count; 17371 17372 ConstExprValue *struct_field_array = create_const_vals(1); 17373 struct_field_array->special = ConstValSpecialStatic; 17374 struct_field_array->type = get_array_type(ira->codegen, type_info_struct_field_type, struct_field_count); 17375 struct_field_array->data.x_array.special = ConstArraySpecialNone; 17376 struct_field_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; 17377 struct_field_array->data.x_array.data.s_none.elements = create_const_vals(struct_field_count); 17378 17379 init_const_slice(ira->codegen, &fields[1], struct_field_array, 0, struct_field_count, false); 17380 17381 for (uint32_t struct_field_index = 0; struct_field_index < struct_field_count; struct_field_index++) { 17382 TypeStructField *struct_field = &type_entry->data.structure.fields[struct_field_index]; 17383 ConstExprValue *struct_field_val = &struct_field_array->data.x_array.data.s_none.elements[struct_field_index]; 17384 17385 struct_field_val->special = ConstValSpecialStatic; 17386 struct_field_val->type = type_info_struct_field_type; 17387 17388 ConstExprValue *inner_fields = create_const_vals(3); 17389 inner_fields[1].special = ConstValSpecialStatic; 17390 inner_fields[1].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_usize); 17391 17392 if (!type_has_bits(struct_field->type_entry)) { 17393 inner_fields[1].data.x_optional = nullptr; 17394 } else { 17395 size_t byte_offset = LLVMOffsetOfElement(ira->codegen->target_data_ref, type_entry->type_ref, struct_field->gen_index); 17396 inner_fields[1].data.x_optional = create_const_vals(1); 17397 inner_fields[1].data.x_optional->special = ConstValSpecialStatic; 17398 inner_fields[1].data.x_optional->type = ira->codegen->builtin_types.entry_usize; 17399 bigint_init_unsigned(&inner_fields[1].data.x_optional->data.x_bigint, byte_offset); 17400 } 17401 17402 inner_fields[2].special = ConstValSpecialStatic; 17403 inner_fields[2].type = ira->codegen->builtin_types.entry_type; 17404 inner_fields[2].data.x_type = struct_field->type_entry; 17405 17406 ConstExprValue *name = create_const_str_lit(ira->codegen, struct_field->name); 17407 init_const_slice(ira->codegen, &inner_fields[0], name, 0, buf_len(struct_field->name), true); 17408 17409 struct_field_val->data.x_struct.fields = inner_fields; 17410 struct_field_val->data.x_struct.parent.id = ConstParentIdArray; 17411 struct_field_val->data.x_struct.parent.data.p_array.array_val = struct_field_array; 17412 struct_field_val->data.x_struct.parent.data.p_array.elem_index = struct_field_index; 17413 } 17414 // defs: []TypeInfo.Definition 17415 ensure_field_index(result->type, "defs", 2); 17416 if ((err = ir_make_type_info_defs(ira, &fields[2], type_entry->data.structure.decls_scope))) 17417 return err; 17418 17419 break; 17420 } 17421 case ZigTypeIdFn: 17422 { 17423 result = create_const_vals(1); 17424 result->special = ConstValSpecialStatic; 17425 result->type = ir_type_info_get_type(ira, "Fn", nullptr); 17426 17427 ConstExprValue *fields = create_const_vals(6); 17428 result->data.x_struct.fields = fields; 17429 17430 // calling_convention: TypeInfo.CallingConvention 17431 ensure_field_index(result->type, "calling_convention", 0); 17432 fields[0].special = ConstValSpecialStatic; 17433 fields[0].type = ir_type_info_get_type(ira, "CallingConvention", nullptr); 17434 bigint_init_unsigned(&fields[0].data.x_enum_tag, type_entry->data.fn.fn_type_id.cc); 17435 // is_generic: bool 17436 ensure_field_index(result->type, "is_generic", 1); 17437 bool is_generic = type_entry->data.fn.is_generic; 17438 fields[1].special = ConstValSpecialStatic; 17439 fields[1].type = ira->codegen->builtin_types.entry_bool; 17440 fields[1].data.x_bool = is_generic; 17441 // is_varargs: bool 17442 ensure_field_index(result->type, "is_var_args", 2); 17443 bool is_varargs = type_entry->data.fn.fn_type_id.is_var_args; 17444 fields[2].special = ConstValSpecialStatic; 17445 fields[2].type = ira->codegen->builtin_types.entry_bool; 17446 fields[2].data.x_bool = type_entry->data.fn.fn_type_id.is_var_args; 17447 // return_type: ?type 17448 ensure_field_index(result->type, "return_type", 3); 17449 fields[3].special = ConstValSpecialStatic; 17450 fields[3].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 17451 if (type_entry->data.fn.fn_type_id.return_type == nullptr) 17452 fields[3].data.x_optional = nullptr; 17453 else { 17454 ConstExprValue *return_type = create_const_vals(1); 17455 return_type->special = ConstValSpecialStatic; 17456 return_type->type = ira->codegen->builtin_types.entry_type; 17457 return_type->data.x_type = type_entry->data.fn.fn_type_id.return_type; 17458 fields[3].data.x_optional = return_type; 17459 } 17460 // async_allocator_type: type 17461 ensure_field_index(result->type, "async_allocator_type", 4); 17462 fields[4].special = ConstValSpecialStatic; 17463 fields[4].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 17464 if (type_entry->data.fn.fn_type_id.async_allocator_type == nullptr) 17465 fields[4].data.x_optional = nullptr; 17466 else { 17467 ConstExprValue *async_alloc_type = create_const_vals(1); 17468 async_alloc_type->special = ConstValSpecialStatic; 17469 async_alloc_type->type = ira->codegen->builtin_types.entry_type; 17470 async_alloc_type->data.x_type = type_entry->data.fn.fn_type_id.async_allocator_type; 17471 fields[4].data.x_optional = async_alloc_type; 17472 } 17473 // args: []TypeInfo.FnArg 17474 ZigType *type_info_fn_arg_type = ir_type_info_get_type(ira, "FnArg", nullptr); 17475 size_t fn_arg_count = type_entry->data.fn.fn_type_id.param_count - 17476 (is_varargs && type_entry->data.fn.fn_type_id.cc != CallingConventionC); 17477 17478 ConstExprValue *fn_arg_array = create_const_vals(1); 17479 fn_arg_array->special = ConstValSpecialStatic; 17480 fn_arg_array->type = get_array_type(ira->codegen, type_info_fn_arg_type, fn_arg_count); 17481 fn_arg_array->data.x_array.special = ConstArraySpecialNone; 17482 fn_arg_array->data.x_array.data.s_none.parent.id = ConstParentIdNone; 17483 fn_arg_array->data.x_array.data.s_none.elements = create_const_vals(fn_arg_count); 17484 17485 init_const_slice(ira->codegen, &fields[5], fn_arg_array, 0, fn_arg_count, false); 17486 17487 for (size_t fn_arg_index = 0; fn_arg_index < fn_arg_count; fn_arg_index++) 17488 { 17489 FnTypeParamInfo *fn_param_info = &type_entry->data.fn.fn_type_id.param_info[fn_arg_index]; 17490 ConstExprValue *fn_arg_val = &fn_arg_array->data.x_array.data.s_none.elements[fn_arg_index]; 17491 17492 fn_arg_val->special = ConstValSpecialStatic; 17493 fn_arg_val->type = type_info_fn_arg_type; 17494 17495 bool arg_is_generic = fn_param_info->type == nullptr; 17496 if (arg_is_generic) assert(is_generic); 17497 17498 ConstExprValue *inner_fields = create_const_vals(3); 17499 inner_fields[0].special = ConstValSpecialStatic; 17500 inner_fields[0].type = ira->codegen->builtin_types.entry_bool; 17501 inner_fields[0].data.x_bool = arg_is_generic; 17502 inner_fields[1].special = ConstValSpecialStatic; 17503 inner_fields[1].type = ira->codegen->builtin_types.entry_bool; 17504 inner_fields[1].data.x_bool = fn_param_info->is_noalias; 17505 inner_fields[2].special = ConstValSpecialStatic; 17506 inner_fields[2].type = get_optional_type(ira->codegen, ira->codegen->builtin_types.entry_type); 17507 17508 if (arg_is_generic) 17509 inner_fields[2].data.x_optional = nullptr; 17510 else { 17511 ConstExprValue *arg_type = create_const_vals(1); 17512 arg_type->special = ConstValSpecialStatic; 17513 arg_type->type = ira->codegen->builtin_types.entry_type; 17514 arg_type->data.x_type = fn_param_info->type; 17515 inner_fields[2].data.x_optional = arg_type; 17516 } 17517 17518 fn_arg_val->data.x_struct.fields = inner_fields; 17519 fn_arg_val->data.x_struct.parent.id = ConstParentIdArray; 17520 fn_arg_val->data.x_struct.parent.data.p_array.array_val = fn_arg_array; 17521 fn_arg_val->data.x_struct.parent.data.p_array.elem_index = fn_arg_index; 17522 } 17523 17524 break; 17525 } 17526 case ZigTypeIdBoundFn: 17527 { 17528 ZigType *fn_type = type_entry->data.bound_fn.fn_type; 17529 assert(fn_type->id == ZigTypeIdFn); 17530 if ((err = ir_make_type_info_value(ira, fn_type, &result))) 17531 return err; 17532 17533 break; 17534 } 17535 } 17536 17537 assert(result != nullptr); 17538 ira->codegen->type_info_cache.put(type_entry, result); 17539 *out = result; 17540 return ErrorNone; 17541 } 17542 17543 static IrInstruction *ir_analyze_instruction_type_info(IrAnalyze *ira, 17544 IrInstructionTypeInfo *instruction) 17545 { 17546 Error err; 17547 IrInstruction *type_value = instruction->type_value->child; 17548 ZigType *type_entry = ir_resolve_type(ira, type_value); 17549 if (type_is_invalid(type_entry)) 17550 return ira->codegen->invalid_instruction; 17551 17552 ZigType *result_type = ir_type_info_get_type(ira, nullptr, nullptr); 17553 17554 ConstExprValue *payload; 17555 if ((err = ir_make_type_info_value(ira, type_entry, &payload))) 17556 return ira->codegen->invalid_instruction; 17557 17558 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 17559 ConstExprValue *out_val = &result->value; 17560 bigint_init_unsigned(&out_val->data.x_union.tag, type_id_index(type_entry)); 17561 out_val->data.x_union.payload = payload; 17562 17563 if (payload != nullptr) { 17564 assert(payload->type->id == ZigTypeIdStruct); 17565 payload->data.x_struct.parent.id = ConstParentIdUnion; 17566 payload->data.x_struct.parent.data.p_union.union_val = out_val; 17567 } 17568 17569 return result; 17570 } 17571 17572 static IrInstruction *ir_analyze_instruction_type_id(IrAnalyze *ira, 17573 IrInstructionTypeId *instruction) 17574 { 17575 IrInstruction *type_value = instruction->type_value->child; 17576 ZigType *type_entry = ir_resolve_type(ira, type_value); 17577 if (type_is_invalid(type_entry)) 17578 return ira->codegen->invalid_instruction; 17579 17580 ConstExprValue *var_value = get_builtin_value(ira->codegen, "TypeId"); 17581 assert(var_value->type->id == ZigTypeIdMetaType); 17582 ZigType *result_type = var_value->data.x_type; 17583 17584 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 17585 bigint_init_unsigned(&result->value.data.x_enum_tag, type_id_index(type_entry)); 17586 return result; 17587 } 17588 17589 static IrInstruction *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira, 17590 IrInstructionSetEvalBranchQuota *instruction) 17591 { 17592 if (ira->new_irb.exec->parent_exec != nullptr && !ira->new_irb.exec->is_generic_instantiation) { 17593 ir_add_error(ira, &instruction->base, 17594 buf_sprintf("@setEvalBranchQuota must be called from the top of the comptime stack")); 17595 return ira->codegen->invalid_instruction; 17596 } 17597 17598 uint64_t new_quota; 17599 if (!ir_resolve_usize(ira, instruction->new_quota->child, &new_quota)) 17600 return ira->codegen->invalid_instruction; 17601 17602 if (new_quota > ira->new_irb.exec->backward_branch_quota) { 17603 ira->new_irb.exec->backward_branch_quota = new_quota; 17604 } 17605 17606 return ir_const_void(ira, &instruction->base); 17607 } 17608 17609 static IrInstruction *ir_analyze_instruction_type_name(IrAnalyze *ira, IrInstructionTypeName *instruction) { 17610 IrInstruction *type_value = instruction->type_value->child; 17611 ZigType *type_entry = ir_resolve_type(ira, type_value); 17612 if (type_is_invalid(type_entry)) 17613 return ira->codegen->invalid_instruction; 17614 17615 if (!type_entry->cached_const_name_val) { 17616 type_entry->cached_const_name_val = create_const_str_lit(ira->codegen, &type_entry->name); 17617 } 17618 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 17619 copy_const_val(&result->value, type_entry->cached_const_name_val, true); 17620 return result; 17621 } 17622 17623 static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstructionCImport *instruction) { 17624 if (ira->codegen->enable_cache) { 17625 ir_add_error(ira, &instruction->base, 17626 buf_sprintf("TODO @cImport is incompatible with --cache on. The cache system currently is unable to detect subsequent changes in .h files.")); 17627 return ira->codegen->invalid_instruction; 17628 } 17629 17630 AstNode *node = instruction->base.source_node; 17631 assert(node->type == NodeTypeFnCallExpr); 17632 AstNode *block_node = node->data.fn_call_expr.params.at(0); 17633 17634 ScopeCImport *cimport_scope = create_cimport_scope(ira->codegen, node, instruction->base.scope); 17635 17636 // Execute the C import block like an inline function 17637 ZigType *void_type = ira->codegen->builtin_types.entry_void; 17638 IrInstruction *cimport_result = ir_eval_const_value(ira->codegen, &cimport_scope->base, block_node, void_type, 17639 ira->new_irb.exec->backward_branch_count, ira->new_irb.exec->backward_branch_quota, nullptr, 17640 &cimport_scope->buf, block_node, nullptr, nullptr); 17641 if (type_is_invalid(cimport_result->value.type)) 17642 return ira->codegen->invalid_instruction; 17643 17644 find_libc_include_path(ira->codegen); 17645 17646 ImportTableEntry *child_import = allocate<ImportTableEntry>(1); 17647 child_import->decls_scope = create_decls_scope(ira->codegen, node, nullptr, nullptr, child_import); 17648 child_import->c_import_node = node; 17649 child_import->package = new_anonymous_package(); 17650 child_import->package->package_table.put(buf_create_from_str("builtin"), ira->codegen->compile_var_package); 17651 child_import->package->package_table.put(buf_create_from_str("std"), ira->codegen->std_package); 17652 child_import->di_file = ZigLLVMCreateFile(ira->codegen->dbuilder, 17653 buf_ptr(buf_create_from_str("cimport.h")), buf_ptr(buf_create_from_str("."))); 17654 17655 ZigList<ErrorMsg *> errors = {0}; 17656 17657 Error err; 17658 if ((err = parse_h_buf(child_import, &errors, &cimport_scope->buf, ira->codegen, node))) { 17659 if (err != ErrorCCompileErrors) { 17660 ir_add_error_node(ira, node, buf_sprintf("C import failed: %s", err_str(err))); 17661 return ira->codegen->invalid_instruction; 17662 } 17663 } 17664 17665 if (errors.length > 0) { 17666 ErrorMsg *parent_err_msg = ir_add_error_node(ira, node, buf_sprintf("C import failed")); 17667 for (size_t i = 0; i < errors.length; i += 1) { 17668 ErrorMsg *err_msg = errors.at(i); 17669 err_msg_add_note(parent_err_msg, err_msg); 17670 } 17671 17672 return ira->codegen->invalid_instruction; 17673 } 17674 17675 if (ira->codegen->verbose_cimport) { 17676 fprintf(stderr, "\nC imports:\n"); 17677 fprintf(stderr, "-----------\n"); 17678 ast_render(ira->codegen, stderr, child_import->root, 4); 17679 } 17680 17681 scan_decls(ira->codegen, child_import->decls_scope, child_import->root); 17682 17683 IrInstruction *result = ir_const(ira, &instruction->base, ira->codegen->builtin_types.entry_namespace); 17684 result->value.data.x_import = child_import; 17685 return result; 17686 } 17687 17688 static IrInstruction *ir_analyze_instruction_c_include(IrAnalyze *ira, IrInstructionCInclude *instruction) { 17689 IrInstruction *name_value = instruction->name->child; 17690 if (type_is_invalid(name_value->value.type)) 17691 return ira->codegen->invalid_instruction; 17692 17693 Buf *include_name = ir_resolve_str(ira, name_value); 17694 if (!include_name) 17695 return ira->codegen->invalid_instruction; 17696 17697 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 17698 // We check for this error in pass1 17699 assert(c_import_buf); 17700 17701 buf_appendf(c_import_buf, "#include <%s>\n", buf_ptr(include_name)); 17702 17703 return ir_const_void(ira, &instruction->base); 17704 } 17705 17706 static IrInstruction *ir_analyze_instruction_c_define(IrAnalyze *ira, IrInstructionCDefine *instruction) { 17707 IrInstruction *name = instruction->name->child; 17708 if (type_is_invalid(name->value.type)) 17709 return ira->codegen->invalid_instruction; 17710 17711 Buf *define_name = ir_resolve_str(ira, name); 17712 if (!define_name) 17713 return ira->codegen->invalid_instruction; 17714 17715 IrInstruction *value = instruction->value->child; 17716 if (type_is_invalid(value->value.type)) 17717 return ira->codegen->invalid_instruction; 17718 17719 Buf *define_value = ir_resolve_str(ira, value); 17720 if (!define_value) 17721 return ira->codegen->invalid_instruction; 17722 17723 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 17724 // We check for this error in pass1 17725 assert(c_import_buf); 17726 17727 buf_appendf(c_import_buf, "#define %s %s\n", buf_ptr(define_name), buf_ptr(define_value)); 17728 17729 return ir_const_void(ira, &instruction->base); 17730 } 17731 17732 static IrInstruction *ir_analyze_instruction_c_undef(IrAnalyze *ira, IrInstructionCUndef *instruction) { 17733 IrInstruction *name = instruction->name->child; 17734 if (type_is_invalid(name->value.type)) 17735 return ira->codegen->invalid_instruction; 17736 17737 Buf *undef_name = ir_resolve_str(ira, name); 17738 if (!undef_name) 17739 return ira->codegen->invalid_instruction; 17740 17741 Buf *c_import_buf = exec_c_import_buf(ira->new_irb.exec); 17742 // We check for this error in pass1 17743 assert(c_import_buf); 17744 17745 buf_appendf(c_import_buf, "#undef %s\n", buf_ptr(undef_name)); 17746 17747 return ir_const_void(ira, &instruction->base); 17748 } 17749 17750 static IrInstruction *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstructionEmbedFile *instruction) { 17751 IrInstruction *name = instruction->name->child; 17752 if (type_is_invalid(name->value.type)) 17753 return ira->codegen->invalid_instruction; 17754 17755 Buf *rel_file_path = ir_resolve_str(ira, name); 17756 if (!rel_file_path) 17757 return ira->codegen->invalid_instruction; 17758 17759 ImportTableEntry *import = get_scope_import(instruction->base.scope); 17760 // figure out absolute path to resource 17761 Buf source_dir_path = BUF_INIT; 17762 os_path_dirname(import->path, &source_dir_path); 17763 17764 Buf *resolve_paths[] = { 17765 &source_dir_path, 17766 rel_file_path, 17767 }; 17768 Buf *file_path = buf_alloc(); 17769 *file_path = os_path_resolve(resolve_paths, 2); 17770 17771 // load from file system into const expr 17772 Buf *file_contents = buf_alloc(); 17773 Error err; 17774 if ((err = file_fetch(ira->codegen, file_path, file_contents))) { 17775 if (err == ErrorFileNotFound) { 17776 ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(file_path))); 17777 return ira->codegen->invalid_instruction; 17778 } else { 17779 ir_add_error(ira, instruction->name, buf_sprintf("unable to open '%s': %s", buf_ptr(file_path), err_str(err))); 17780 return ira->codegen->invalid_instruction; 17781 } 17782 } 17783 17784 ZigType *result_type = get_array_type(ira->codegen, 17785 ira->codegen->builtin_types.entry_u8, buf_len(file_contents)); 17786 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 17787 init_const_str_lit(ira->codegen, &result->value, file_contents); 17788 return result; 17789 } 17790 17791 static IrInstruction *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructionCmpxchg *instruction) { 17792 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->type_value->child); 17793 if (type_is_invalid(operand_type)) 17794 return ira->codegen->invalid_instruction; 17795 17796 IrInstruction *ptr = instruction->ptr->child; 17797 if (type_is_invalid(ptr->value.type)) 17798 return ira->codegen->invalid_instruction; 17799 17800 // TODO let this be volatile 17801 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 17802 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr, ptr_type); 17803 if (type_is_invalid(casted_ptr->value.type)) 17804 return ira->codegen->invalid_instruction; 17805 17806 IrInstruction *cmp_value = instruction->cmp_value->child; 17807 if (type_is_invalid(cmp_value->value.type)) 17808 return ira->codegen->invalid_instruction; 17809 17810 IrInstruction *new_value = instruction->new_value->child; 17811 if (type_is_invalid(new_value->value.type)) 17812 return ira->codegen->invalid_instruction; 17813 17814 IrInstruction *success_order_value = instruction->success_order_value->child; 17815 if (type_is_invalid(success_order_value->value.type)) 17816 return ira->codegen->invalid_instruction; 17817 17818 AtomicOrder success_order; 17819 if (!ir_resolve_atomic_order(ira, success_order_value, &success_order)) 17820 return ira->codegen->invalid_instruction; 17821 17822 IrInstruction *failure_order_value = instruction->failure_order_value->child; 17823 if (type_is_invalid(failure_order_value->value.type)) 17824 return ira->codegen->invalid_instruction; 17825 17826 AtomicOrder failure_order; 17827 if (!ir_resolve_atomic_order(ira, failure_order_value, &failure_order)) 17828 return ira->codegen->invalid_instruction; 17829 17830 IrInstruction *casted_cmp_value = ir_implicit_cast(ira, cmp_value, operand_type); 17831 if (type_is_invalid(casted_cmp_value->value.type)) 17832 return ira->codegen->invalid_instruction; 17833 17834 IrInstruction *casted_new_value = ir_implicit_cast(ira, new_value, operand_type); 17835 if (type_is_invalid(casted_new_value->value.type)) 17836 return ira->codegen->invalid_instruction; 17837 17838 if (success_order < AtomicOrderMonotonic) { 17839 ir_add_error(ira, success_order_value, 17840 buf_sprintf("success atomic ordering must be Monotonic or stricter")); 17841 return ira->codegen->invalid_instruction; 17842 } 17843 if (failure_order < AtomicOrderMonotonic) { 17844 ir_add_error(ira, failure_order_value, 17845 buf_sprintf("failure atomic ordering must be Monotonic or stricter")); 17846 return ira->codegen->invalid_instruction; 17847 } 17848 if (failure_order > success_order) { 17849 ir_add_error(ira, failure_order_value, 17850 buf_sprintf("failure atomic ordering must be no stricter than success")); 17851 return ira->codegen->invalid_instruction; 17852 } 17853 if (failure_order == AtomicOrderRelease || failure_order == AtomicOrderAcqRel) { 17854 ir_add_error(ira, failure_order_value, 17855 buf_sprintf("failure atomic ordering must not be Release or AcqRel")); 17856 return ira->codegen->invalid_instruction; 17857 } 17858 17859 if (instr_is_comptime(casted_ptr) && instr_is_comptime(casted_cmp_value) && instr_is_comptime(casted_new_value)) { 17860 zig_panic("TODO compile-time execution of cmpxchg"); 17861 } 17862 17863 IrInstruction *result = ir_build_cmpxchg(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 17864 nullptr, casted_ptr, casted_cmp_value, casted_new_value, nullptr, nullptr, instruction->is_weak, 17865 operand_type, success_order, failure_order); 17866 result->value.type = get_optional_type(ira->codegen, operand_type); 17867 ir_add_alloca(ira, result, result->value.type); 17868 return result; 17869 } 17870 17871 static IrInstruction *ir_analyze_instruction_fence(IrAnalyze *ira, IrInstructionFence *instruction) { 17872 IrInstruction *order_value = instruction->order_value->child; 17873 if (type_is_invalid(order_value->value.type)) 17874 return ira->codegen->invalid_instruction; 17875 17876 AtomicOrder order; 17877 if (!ir_resolve_atomic_order(ira, order_value, &order)) 17878 return ira->codegen->invalid_instruction; 17879 17880 IrInstruction *result = ir_build_fence(&ira->new_irb, 17881 instruction->base.scope, instruction->base.source_node, order_value, order); 17882 result->value.type = ira->codegen->builtin_types.entry_void; 17883 return result; 17884 } 17885 17886 static IrInstruction *ir_analyze_instruction_truncate(IrAnalyze *ira, IrInstructionTruncate *instruction) { 17887 IrInstruction *dest_type_value = instruction->dest_type->child; 17888 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 17889 if (type_is_invalid(dest_type)) 17890 return ira->codegen->invalid_instruction; 17891 17892 if (dest_type->id != ZigTypeIdInt && 17893 dest_type->id != ZigTypeIdComptimeInt) 17894 { 17895 ir_add_error(ira, dest_type_value, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 17896 return ira->codegen->invalid_instruction; 17897 } 17898 17899 IrInstruction *target = instruction->target->child; 17900 ZigType *src_type = target->value.type; 17901 if (type_is_invalid(src_type)) 17902 return ira->codegen->invalid_instruction; 17903 17904 if (src_type->id != ZigTypeIdInt && 17905 src_type->id != ZigTypeIdComptimeInt) 17906 { 17907 ir_add_error(ira, target, buf_sprintf("expected integer type, found '%s'", buf_ptr(&src_type->name))); 17908 return ira->codegen->invalid_instruction; 17909 } 17910 17911 if (src_type->data.integral.is_signed != dest_type->data.integral.is_signed) { 17912 const char *sign_str = dest_type->data.integral.is_signed ? "signed" : "unsigned"; 17913 ir_add_error(ira, target, buf_sprintf("expected %s integer type, found '%s'", sign_str, buf_ptr(&src_type->name))); 17914 return ira->codegen->invalid_instruction; 17915 } else if (src_type->data.integral.bit_count < dest_type->data.integral.bit_count) { 17916 ir_add_error(ira, target, buf_sprintf("type '%s' has fewer bits than destination type '%s'", 17917 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 17918 return ira->codegen->invalid_instruction; 17919 } 17920 17921 if (target->value.special == ConstValSpecialStatic) { 17922 IrInstruction *result = ir_const(ira, &instruction->base, dest_type); 17923 bigint_truncate(&result->value.data.x_bigint, &target->value.data.x_bigint, 17924 dest_type->data.integral.bit_count, dest_type->data.integral.is_signed); 17925 return result; 17926 } 17927 17928 IrInstruction *new_instruction = ir_build_truncate(&ira->new_irb, instruction->base.scope, 17929 instruction->base.source_node, dest_type_value, target); 17930 new_instruction->value.type = dest_type; 17931 return new_instruction; 17932 } 17933 17934 static IrInstruction *ir_analyze_instruction_int_cast(IrAnalyze *ira, IrInstructionIntCast *instruction) { 17935 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 17936 if (type_is_invalid(dest_type)) 17937 return ira->codegen->invalid_instruction; 17938 17939 if (dest_type->id != ZigTypeIdInt) { 17940 ir_add_error(ira, instruction->dest_type, buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 17941 return ira->codegen->invalid_instruction; 17942 } 17943 17944 IrInstruction *target = instruction->target->child; 17945 if (type_is_invalid(target->value.type)) 17946 return ira->codegen->invalid_instruction; 17947 17948 if (target->value.type->id == ZigTypeIdComptimeInt) { 17949 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { 17950 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpNumLitToConcrete, false); 17951 } else { 17952 return ira->codegen->invalid_instruction; 17953 } 17954 } 17955 17956 if (target->value.type->id != ZigTypeIdInt) { 17957 ir_add_error(ira, instruction->target, buf_sprintf("expected integer type, found '%s'", 17958 buf_ptr(&target->value.type->name))); 17959 return ira->codegen->invalid_instruction; 17960 } 17961 17962 return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); 17963 } 17964 17965 static IrInstruction *ir_analyze_instruction_float_cast(IrAnalyze *ira, IrInstructionFloatCast *instruction) { 17966 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 17967 if (type_is_invalid(dest_type)) 17968 return ira->codegen->invalid_instruction; 17969 17970 if (dest_type->id != ZigTypeIdFloat) { 17971 ir_add_error(ira, instruction->dest_type, 17972 buf_sprintf("expected float type, found '%s'", buf_ptr(&dest_type->name))); 17973 return ira->codegen->invalid_instruction; 17974 } 17975 17976 IrInstruction *target = instruction->target->child; 17977 if (type_is_invalid(target->value.type)) 17978 return ira->codegen->invalid_instruction; 17979 17980 if (target->value.type->id == ZigTypeIdComptimeInt || 17981 target->value.type->id == ZigTypeIdComptimeFloat) 17982 { 17983 if (ir_num_lit_fits_in_other_type(ira, target, dest_type, true)) { 17984 CastOp op; 17985 if (target->value.type->id == ZigTypeIdComptimeInt) { 17986 op = CastOpIntToFloat; 17987 } else { 17988 op = CastOpNumLitToConcrete; 17989 } 17990 return ir_resolve_cast(ira, &instruction->base, target, dest_type, op, false); 17991 } else { 17992 return ira->codegen->invalid_instruction; 17993 } 17994 } 17995 17996 if (target->value.type->id != ZigTypeIdFloat) { 17997 ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", 17998 buf_ptr(&target->value.type->name))); 17999 return ira->codegen->invalid_instruction; 18000 } 18001 18002 return ir_analyze_widen_or_shorten(ira, &instruction->base, target, dest_type); 18003 } 18004 18005 static IrInstruction *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstructionErrSetCast *instruction) { 18006 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 18007 if (type_is_invalid(dest_type)) 18008 return ira->codegen->invalid_instruction; 18009 18010 if (dest_type->id != ZigTypeIdErrorSet) { 18011 ir_add_error(ira, instruction->dest_type, 18012 buf_sprintf("expected error set type, found '%s'", buf_ptr(&dest_type->name))); 18013 return ira->codegen->invalid_instruction; 18014 } 18015 18016 IrInstruction *target = instruction->target->child; 18017 if (type_is_invalid(target->value.type)) 18018 return ira->codegen->invalid_instruction; 18019 18020 if (target->value.type->id != ZigTypeIdErrorSet) { 18021 ir_add_error(ira, instruction->target, 18022 buf_sprintf("expected error set type, found '%s'", buf_ptr(&target->value.type->name))); 18023 return ira->codegen->invalid_instruction; 18024 } 18025 18026 return ir_analyze_err_set_cast(ira, &instruction->base, target, dest_type); 18027 } 18028 18029 static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) { 18030 Error err; 18031 18032 if (ty->id == ZigTypeIdPointer) { 18033 if ((err = type_resolve(ira->codegen, ty->data.pointer.child_type, ResolveStatusAlignmentKnown))) 18034 return err; 18035 } 18036 18037 *result_align = get_ptr_align(ira->codegen, ty); 18038 return ErrorNone; 18039 } 18040 18041 static IrInstruction *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstructionFromBytes *instruction) { 18042 Error err; 18043 18044 ZigType *dest_child_type = ir_resolve_type(ira, instruction->dest_child_type->child); 18045 if (type_is_invalid(dest_child_type)) 18046 return ira->codegen->invalid_instruction; 18047 18048 IrInstruction *target = instruction->target->child; 18049 if (type_is_invalid(target->value.type)) 18050 return ira->codegen->invalid_instruction; 18051 18052 bool src_ptr_const; 18053 bool src_ptr_volatile; 18054 uint32_t src_ptr_align; 18055 if (target->value.type->id == ZigTypeIdPointer) { 18056 src_ptr_const = target->value.type->data.pointer.is_const; 18057 src_ptr_volatile = target->value.type->data.pointer.is_volatile; 18058 18059 if ((err = resolve_ptr_align(ira, target->value.type, &src_ptr_align))) 18060 return ira->codegen->invalid_instruction; 18061 } else if (is_slice(target->value.type)) { 18062 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry; 18063 src_ptr_const = src_ptr_type->data.pointer.is_const; 18064 src_ptr_volatile = src_ptr_type->data.pointer.is_volatile; 18065 18066 if ((err = resolve_ptr_align(ira, src_ptr_type, &src_ptr_align))) 18067 return ira->codegen->invalid_instruction; 18068 } else { 18069 src_ptr_const = true; 18070 src_ptr_volatile = false; 18071 18072 if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusAlignmentKnown))) 18073 return ira->codegen->invalid_instruction; 18074 18075 src_ptr_align = get_abi_alignment(ira->codegen, target->value.type); 18076 } 18077 18078 if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusSizeKnown))) 18079 return ira->codegen->invalid_instruction; 18080 18081 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_child_type, 18082 src_ptr_const, src_ptr_volatile, PtrLenUnknown, 18083 src_ptr_align, 0, 0); 18084 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); 18085 18086 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 18087 src_ptr_const, src_ptr_volatile, PtrLenUnknown, 18088 src_ptr_align, 0, 0); 18089 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr); 18090 18091 IrInstruction *casted_value = ir_implicit_cast(ira, target, u8_slice); 18092 if (type_is_invalid(casted_value->value.type)) 18093 return ira->codegen->invalid_instruction; 18094 18095 bool have_known_len = false; 18096 uint64_t known_len; 18097 18098 if (instr_is_comptime(casted_value)) { 18099 ConstExprValue *val = ir_resolve_const(ira, casted_value, UndefBad); 18100 if (!val) 18101 return ira->codegen->invalid_instruction; 18102 18103 ConstExprValue *len_val = &val->data.x_struct.fields[slice_len_index]; 18104 if (value_is_comptime(len_val)) { 18105 known_len = bigint_as_unsigned(&len_val->data.x_bigint); 18106 have_known_len = true; 18107 } 18108 } 18109 18110 if (casted_value->value.data.rh_slice.id == RuntimeHintSliceIdLen) { 18111 known_len = casted_value->value.data.rh_slice.len; 18112 have_known_len = true; 18113 } 18114 18115 if (have_known_len) { 18116 uint64_t child_type_size = type_size(ira->codegen, dest_child_type); 18117 uint64_t remainder = known_len % child_type_size; 18118 if (remainder != 0) { 18119 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 18120 buf_sprintf("unable to convert [%" ZIG_PRI_u64 "]u8 to %s: size mismatch", 18121 known_len, buf_ptr(&dest_slice_type->name))); 18122 add_error_note(ira->codegen, msg, instruction->dest_child_type->source_node, 18123 buf_sprintf("%s has size %" ZIG_PRI_u64 "; remaining bytes: %" ZIG_PRI_u64, 18124 buf_ptr(&dest_child_type->name), child_type_size, remainder)); 18125 return ira->codegen->invalid_instruction; 18126 } 18127 } 18128 18129 return ir_resolve_cast(ira, &instruction->base, casted_value, dest_slice_type, CastOpResizeSlice, true); 18130 } 18131 18132 static IrInstruction *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstructionToBytes *instruction) { 18133 Error err; 18134 18135 IrInstruction *target = instruction->target->child; 18136 if (type_is_invalid(target->value.type)) 18137 return ira->codegen->invalid_instruction; 18138 18139 if (!is_slice(target->value.type)) { 18140 ir_add_error(ira, instruction->target, 18141 buf_sprintf("expected slice, found '%s'", buf_ptr(&target->value.type->name))); 18142 return ira->codegen->invalid_instruction; 18143 } 18144 18145 ZigType *src_ptr_type = target->value.type->data.structure.fields[slice_ptr_index].type_entry; 18146 18147 uint32_t alignment; 18148 if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment))) 18149 return ira->codegen->invalid_instruction; 18150 18151 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 18152 src_ptr_type->data.pointer.is_const, src_ptr_type->data.pointer.is_volatile, PtrLenUnknown, 18153 alignment, 0, 0); 18154 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type); 18155 18156 return ir_resolve_cast(ira, &instruction->base, target, dest_slice_type, CastOpResizeSlice, true); 18157 } 18158 18159 static IrInstruction *ir_analyze_instruction_int_to_float(IrAnalyze *ira, IrInstructionIntToFloat *instruction) { 18160 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 18161 if (type_is_invalid(dest_type)) 18162 return ira->codegen->invalid_instruction; 18163 18164 IrInstruction *target = instruction->target->child; 18165 if (type_is_invalid(target->value.type)) 18166 return ira->codegen->invalid_instruction; 18167 18168 if (target->value.type->id != ZigTypeIdInt && target->value.type->id != ZigTypeIdComptimeInt) { 18169 ir_add_error(ira, instruction->target, buf_sprintf("expected int type, found '%s'", 18170 buf_ptr(&target->value.type->name))); 18171 return ira->codegen->invalid_instruction; 18172 } 18173 18174 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpIntToFloat, false); 18175 } 18176 18177 static IrInstruction *ir_analyze_instruction_float_to_int(IrAnalyze *ira, IrInstructionFloatToInt *instruction) { 18178 ZigType *dest_type = ir_resolve_type(ira, instruction->dest_type->child); 18179 if (type_is_invalid(dest_type)) 18180 return ira->codegen->invalid_instruction; 18181 18182 IrInstruction *target = instruction->target->child; 18183 if (type_is_invalid(target->value.type)) 18184 return ira->codegen->invalid_instruction; 18185 18186 if (target->value.type->id == ZigTypeIdComptimeInt) { 18187 return ir_implicit_cast(ira, target, dest_type); 18188 } 18189 18190 if (target->value.type->id != ZigTypeIdFloat && target->value.type->id != ZigTypeIdComptimeFloat) { 18191 ir_add_error(ira, instruction->target, buf_sprintf("expected float type, found '%s'", 18192 buf_ptr(&target->value.type->name))); 18193 return ira->codegen->invalid_instruction; 18194 } 18195 18196 return ir_resolve_cast(ira, &instruction->base, target, dest_type, CastOpFloatToInt, false); 18197 } 18198 18199 static IrInstruction *ir_analyze_instruction_err_to_int(IrAnalyze *ira, IrInstructionErrToInt *instruction) { 18200 IrInstruction *target = instruction->target->child; 18201 if (type_is_invalid(target->value.type)) 18202 return ira->codegen->invalid_instruction; 18203 18204 IrInstruction *casted_target; 18205 if (target->value.type->id == ZigTypeIdErrorSet) { 18206 casted_target = target; 18207 } else { 18208 casted_target = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_global_error_set); 18209 if (type_is_invalid(casted_target->value.type)) 18210 return ira->codegen->invalid_instruction; 18211 } 18212 18213 return ir_analyze_err_to_int(ira, &instruction->base, casted_target, ira->codegen->err_tag_type); 18214 } 18215 18216 static IrInstruction *ir_analyze_instruction_int_to_err(IrAnalyze *ira, IrInstructionIntToErr *instruction) { 18217 IrInstruction *target = instruction->target->child; 18218 if (type_is_invalid(target->value.type)) 18219 return ira->codegen->invalid_instruction; 18220 18221 IrInstruction *casted_target = ir_implicit_cast(ira, target, ira->codegen->err_tag_type); 18222 if (type_is_invalid(casted_target->value.type)) 18223 return ira->codegen->invalid_instruction; 18224 18225 return ir_analyze_int_to_err(ira, &instruction->base, casted_target, ira->codegen->builtin_types.entry_global_error_set); 18226 } 18227 18228 static IrInstruction *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstructionBoolToInt *instruction) { 18229 IrInstruction *target = instruction->target->child; 18230 if (type_is_invalid(target->value.type)) 18231 return ira->codegen->invalid_instruction; 18232 18233 if (target->value.type->id != ZigTypeIdBool) { 18234 ir_add_error(ira, instruction->target, buf_sprintf("expected bool, found '%s'", 18235 buf_ptr(&target->value.type->name))); 18236 return ira->codegen->invalid_instruction; 18237 } 18238 18239 if (instr_is_comptime(target)) { 18240 bool is_true; 18241 if (!ir_resolve_bool(ira, target, &is_true)) 18242 return ira->codegen->invalid_instruction; 18243 18244 return ir_const_unsigned(ira, &instruction->base, is_true ? 1 : 0); 18245 } 18246 18247 ZigType *u1_type = get_int_type(ira->codegen, false, 1); 18248 return ir_resolve_cast(ira, &instruction->base, target, u1_type, CastOpBoolToInt, false); 18249 } 18250 18251 static IrInstruction *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstructionIntType *instruction) { 18252 IrInstruction *is_signed_value = instruction->is_signed->child; 18253 bool is_signed; 18254 if (!ir_resolve_bool(ira, is_signed_value, &is_signed)) 18255 return ira->codegen->invalid_instruction; 18256 18257 IrInstruction *bit_count_value = instruction->bit_count->child; 18258 uint64_t bit_count; 18259 if (!ir_resolve_unsigned(ira, bit_count_value, ira->codegen->builtin_types.entry_u16, &bit_count)) 18260 return ira->codegen->invalid_instruction; 18261 18262 return ir_const_type(ira, &instruction->base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count)); 18263 } 18264 18265 static IrInstruction *ir_analyze_instruction_bool_not(IrAnalyze *ira, IrInstructionBoolNot *instruction) { 18266 IrInstruction *value = instruction->value->child; 18267 if (type_is_invalid(value->value.type)) 18268 return ira->codegen->invalid_instruction; 18269 18270 ZigType *bool_type = ira->codegen->builtin_types.entry_bool; 18271 18272 IrInstruction *casted_value = ir_implicit_cast(ira, value, bool_type); 18273 if (type_is_invalid(casted_value->value.type)) 18274 return ira->codegen->invalid_instruction; 18275 18276 if (instr_is_comptime(casted_value)) { 18277 ConstExprValue *value = ir_resolve_const(ira, casted_value, UndefBad); 18278 if (value == nullptr) 18279 return ira->codegen->invalid_instruction; 18280 18281 return ir_const_bool(ira, &instruction->base, !value->data.x_bool); 18282 } 18283 18284 IrInstruction *result = ir_build_bool_not(&ira->new_irb, instruction->base.scope, 18285 instruction->base.source_node, casted_value); 18286 result->value.type = bool_type; 18287 return result; 18288 } 18289 18290 static IrInstruction *ir_analyze_instruction_memset(IrAnalyze *ira, IrInstructionMemset *instruction) { 18291 Error err; 18292 18293 IrInstruction *dest_ptr = instruction->dest_ptr->child; 18294 if (type_is_invalid(dest_ptr->value.type)) 18295 return ira->codegen->invalid_instruction; 18296 18297 IrInstruction *byte_value = instruction->byte->child; 18298 if (type_is_invalid(byte_value->value.type)) 18299 return ira->codegen->invalid_instruction; 18300 18301 IrInstruction *count_value = instruction->count->child; 18302 if (type_is_invalid(count_value->value.type)) 18303 return ira->codegen->invalid_instruction; 18304 18305 ZigType *dest_uncasted_type = dest_ptr->value.type; 18306 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 18307 dest_uncasted_type->data.pointer.is_volatile; 18308 18309 ZigType *usize = ira->codegen->builtin_types.entry_usize; 18310 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 18311 uint32_t dest_align; 18312 if (dest_uncasted_type->id == ZigTypeIdPointer) { 18313 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 18314 return ira->codegen->invalid_instruction; 18315 } else { 18316 dest_align = get_abi_alignment(ira->codegen, u8); 18317 } 18318 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 18319 PtrLenUnknown, dest_align, 0, 0); 18320 18321 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr); 18322 if (type_is_invalid(casted_dest_ptr->value.type)) 18323 return ira->codegen->invalid_instruction; 18324 18325 IrInstruction *casted_byte = ir_implicit_cast(ira, byte_value, u8); 18326 if (type_is_invalid(casted_byte->value.type)) 18327 return ira->codegen->invalid_instruction; 18328 18329 IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); 18330 if (type_is_invalid(casted_count->value.type)) 18331 return ira->codegen->invalid_instruction; 18332 18333 if (casted_dest_ptr->value.special == ConstValSpecialStatic && 18334 casted_byte->value.special == ConstValSpecialStatic && 18335 casted_count->value.special == ConstValSpecialStatic && 18336 casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) 18337 { 18338 ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; 18339 18340 ConstExprValue *dest_elements; 18341 size_t start; 18342 size_t bound_end; 18343 switch (dest_ptr_val->data.x_ptr.special) { 18344 case ConstPtrSpecialInvalid: 18345 case ConstPtrSpecialDiscard: 18346 zig_unreachable(); 18347 case ConstPtrSpecialRef: 18348 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 18349 start = 0; 18350 bound_end = 1; 18351 break; 18352 case ConstPtrSpecialBaseArray: 18353 { 18354 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 18355 expand_undef_array(ira->codegen, array_val); 18356 dest_elements = array_val->data.x_array.data.s_none.elements; 18357 start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 18358 bound_end = array_val->type->data.array.len; 18359 break; 18360 } 18361 case ConstPtrSpecialBaseStruct: 18362 zig_panic("TODO memset on const inner struct"); 18363 case ConstPtrSpecialHardCodedAddr: 18364 zig_unreachable(); 18365 case ConstPtrSpecialFunction: 18366 zig_panic("TODO memset on ptr cast from function"); 18367 } 18368 18369 size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); 18370 size_t end = start + count; 18371 if (end > bound_end) { 18372 ir_add_error(ira, count_value, buf_sprintf("out of bounds pointer access")); 18373 return ira->codegen->invalid_instruction; 18374 } 18375 18376 ConstExprValue *byte_val = &casted_byte->value; 18377 for (size_t i = start; i < end; i += 1) { 18378 dest_elements[i] = *byte_val; 18379 } 18380 18381 return ir_const_void(ira, &instruction->base); 18382 } 18383 18384 IrInstruction *result = ir_build_memset(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 18385 casted_dest_ptr, casted_byte, casted_count); 18386 result->value.type = ira->codegen->builtin_types.entry_void; 18387 return result; 18388 } 18389 18390 static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructionMemcpy *instruction) { 18391 Error err; 18392 18393 IrInstruction *dest_ptr = instruction->dest_ptr->child; 18394 if (type_is_invalid(dest_ptr->value.type)) 18395 return ira->codegen->invalid_instruction; 18396 18397 IrInstruction *src_ptr = instruction->src_ptr->child; 18398 if (type_is_invalid(src_ptr->value.type)) 18399 return ira->codegen->invalid_instruction; 18400 18401 IrInstruction *count_value = instruction->count->child; 18402 if (type_is_invalid(count_value->value.type)) 18403 return ira->codegen->invalid_instruction; 18404 18405 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 18406 ZigType *dest_uncasted_type = dest_ptr->value.type; 18407 ZigType *src_uncasted_type = src_ptr->value.type; 18408 bool dest_is_volatile = (dest_uncasted_type->id == ZigTypeIdPointer) && 18409 dest_uncasted_type->data.pointer.is_volatile; 18410 bool src_is_volatile = (src_uncasted_type->id == ZigTypeIdPointer) && 18411 src_uncasted_type->data.pointer.is_volatile; 18412 18413 uint32_t dest_align; 18414 if (dest_uncasted_type->id == ZigTypeIdPointer) { 18415 if ((err = resolve_ptr_align(ira, dest_uncasted_type, &dest_align))) 18416 return ira->codegen->invalid_instruction; 18417 } else { 18418 dest_align = get_abi_alignment(ira->codegen, u8); 18419 } 18420 18421 uint32_t src_align; 18422 if (src_uncasted_type->id == ZigTypeIdPointer) { 18423 if ((err = resolve_ptr_align(ira, src_uncasted_type, &src_align))) 18424 return ira->codegen->invalid_instruction; 18425 } else { 18426 src_align = get_abi_alignment(ira->codegen, u8); 18427 } 18428 18429 ZigType *usize = ira->codegen->builtin_types.entry_usize; 18430 ZigType *u8_ptr_mut = get_pointer_to_type_extra(ira->codegen, u8, false, dest_is_volatile, 18431 PtrLenUnknown, dest_align, 0, 0); 18432 ZigType *u8_ptr_const = get_pointer_to_type_extra(ira->codegen, u8, true, src_is_volatile, 18433 PtrLenUnknown, src_align, 0, 0); 18434 18435 IrInstruction *casted_dest_ptr = ir_implicit_cast(ira, dest_ptr, u8_ptr_mut); 18436 if (type_is_invalid(casted_dest_ptr->value.type)) 18437 return ira->codegen->invalid_instruction; 18438 18439 IrInstruction *casted_src_ptr = ir_implicit_cast(ira, src_ptr, u8_ptr_const); 18440 if (type_is_invalid(casted_src_ptr->value.type)) 18441 return ira->codegen->invalid_instruction; 18442 18443 IrInstruction *casted_count = ir_implicit_cast(ira, count_value, usize); 18444 if (type_is_invalid(casted_count->value.type)) 18445 return ira->codegen->invalid_instruction; 18446 18447 if (casted_dest_ptr->value.special == ConstValSpecialStatic && 18448 casted_src_ptr->value.special == ConstValSpecialStatic && 18449 casted_count->value.special == ConstValSpecialStatic && 18450 casted_dest_ptr->value.data.x_ptr.special != ConstPtrSpecialHardCodedAddr) 18451 { 18452 size_t count = bigint_as_unsigned(&casted_count->value.data.x_bigint); 18453 18454 ConstExprValue *dest_ptr_val = &casted_dest_ptr->value; 18455 ConstExprValue *dest_elements; 18456 size_t dest_start; 18457 size_t dest_end; 18458 switch (dest_ptr_val->data.x_ptr.special) { 18459 case ConstPtrSpecialInvalid: 18460 case ConstPtrSpecialDiscard: 18461 zig_unreachable(); 18462 case ConstPtrSpecialRef: 18463 dest_elements = dest_ptr_val->data.x_ptr.data.ref.pointee; 18464 dest_start = 0; 18465 dest_end = 1; 18466 break; 18467 case ConstPtrSpecialBaseArray: 18468 { 18469 ConstExprValue *array_val = dest_ptr_val->data.x_ptr.data.base_array.array_val; 18470 expand_undef_array(ira->codegen, array_val); 18471 dest_elements = array_val->data.x_array.data.s_none.elements; 18472 dest_start = dest_ptr_val->data.x_ptr.data.base_array.elem_index; 18473 dest_end = array_val->type->data.array.len; 18474 break; 18475 } 18476 case ConstPtrSpecialBaseStruct: 18477 zig_panic("TODO memcpy on const inner struct"); 18478 case ConstPtrSpecialHardCodedAddr: 18479 zig_unreachable(); 18480 case ConstPtrSpecialFunction: 18481 zig_panic("TODO memcpy on ptr cast from function"); 18482 } 18483 18484 if (dest_start + count > dest_end) { 18485 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); 18486 return ira->codegen->invalid_instruction; 18487 } 18488 18489 ConstExprValue *src_ptr_val = &casted_src_ptr->value; 18490 ConstExprValue *src_elements; 18491 size_t src_start; 18492 size_t src_end; 18493 18494 switch (src_ptr_val->data.x_ptr.special) { 18495 case ConstPtrSpecialInvalid: 18496 case ConstPtrSpecialDiscard: 18497 zig_unreachable(); 18498 case ConstPtrSpecialRef: 18499 src_elements = src_ptr_val->data.x_ptr.data.ref.pointee; 18500 src_start = 0; 18501 src_end = 1; 18502 break; 18503 case ConstPtrSpecialBaseArray: 18504 { 18505 ConstExprValue *array_val = src_ptr_val->data.x_ptr.data.base_array.array_val; 18506 expand_undef_array(ira->codegen, array_val); 18507 src_elements = array_val->data.x_array.data.s_none.elements; 18508 src_start = src_ptr_val->data.x_ptr.data.base_array.elem_index; 18509 src_end = array_val->type->data.array.len; 18510 break; 18511 } 18512 case ConstPtrSpecialBaseStruct: 18513 zig_panic("TODO memcpy on const inner struct"); 18514 case ConstPtrSpecialHardCodedAddr: 18515 zig_unreachable(); 18516 case ConstPtrSpecialFunction: 18517 zig_panic("TODO memcpy on ptr cast from function"); 18518 } 18519 18520 if (src_start + count > src_end) { 18521 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds pointer access")); 18522 return ira->codegen->invalid_instruction; 18523 } 18524 18525 // TODO check for noalias violations - this should be generalized to work for any function 18526 18527 for (size_t i = 0; i < count; i += 1) { 18528 dest_elements[dest_start + i] = src_elements[src_start + i]; 18529 } 18530 18531 return ir_const_void(ira, &instruction->base); 18532 } 18533 18534 IrInstruction *result = ir_build_memcpy(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 18535 casted_dest_ptr, casted_src_ptr, casted_count); 18536 result->value.type = ira->codegen->builtin_types.entry_void; 18537 return result; 18538 } 18539 18540 static IrInstruction *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstructionSlice *instruction) { 18541 IrInstruction *ptr_ptr = instruction->ptr->child; 18542 if (type_is_invalid(ptr_ptr->value.type)) 18543 return ira->codegen->invalid_instruction; 18544 18545 ZigType *ptr_type = ptr_ptr->value.type; 18546 assert(ptr_type->id == ZigTypeIdPointer); 18547 ZigType *array_type = ptr_type->data.pointer.child_type; 18548 18549 IrInstruction *start = instruction->start->child; 18550 if (type_is_invalid(start->value.type)) 18551 return ira->codegen->invalid_instruction; 18552 18553 ZigType *usize = ira->codegen->builtin_types.entry_usize; 18554 IrInstruction *casted_start = ir_implicit_cast(ira, start, usize); 18555 if (type_is_invalid(casted_start->value.type)) 18556 return ira->codegen->invalid_instruction; 18557 18558 IrInstruction *end; 18559 if (instruction->end) { 18560 end = instruction->end->child; 18561 if (type_is_invalid(end->value.type)) 18562 return ira->codegen->invalid_instruction; 18563 end = ir_implicit_cast(ira, end, usize); 18564 if (type_is_invalid(end->value.type)) 18565 return ira->codegen->invalid_instruction; 18566 } else { 18567 end = nullptr; 18568 } 18569 18570 ZigType *return_type; 18571 18572 if (array_type->id == ZigTypeIdArray) { 18573 bool is_comptime_const = ptr_ptr->value.special == ConstValSpecialStatic && 18574 ptr_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeConst; 18575 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, array_type->data.array.child_type, 18576 ptr_type->data.pointer.is_const || is_comptime_const, 18577 ptr_type->data.pointer.is_volatile, 18578 PtrLenUnknown, 18579 ptr_type->data.pointer.explicit_alignment, 0, 0); 18580 return_type = get_slice_type(ira->codegen, slice_ptr_type); 18581 } else if (array_type->id == ZigTypeIdPointer) { 18582 if (array_type->data.pointer.ptr_len == PtrLenSingle) { 18583 ZigType *main_type = array_type->data.pointer.child_type; 18584 if (main_type->id == ZigTypeIdArray) { 18585 ZigType *slice_ptr_type = get_pointer_to_type_extra(ira->codegen, 18586 main_type->data.pointer.child_type, 18587 array_type->data.pointer.is_const, array_type->data.pointer.is_volatile, 18588 PtrLenUnknown, 18589 array_type->data.pointer.explicit_alignment, 0, 0); 18590 return_type = get_slice_type(ira->codegen, slice_ptr_type); 18591 } else { 18592 ir_add_error(ira, &instruction->base, buf_sprintf("slice of single-item pointer")); 18593 return ira->codegen->invalid_instruction; 18594 } 18595 } else { 18596 return_type = get_slice_type(ira->codegen, array_type); 18597 if (!end) { 18598 ir_add_error(ira, &instruction->base, buf_sprintf("slice of pointer must include end value")); 18599 return ira->codegen->invalid_instruction; 18600 } 18601 } 18602 } else if (is_slice(array_type)) { 18603 ZigType *ptr_type = array_type->data.structure.fields[slice_ptr_index].type_entry; 18604 return_type = get_slice_type(ira->codegen, ptr_type); 18605 } else { 18606 ir_add_error(ira, &instruction->base, 18607 buf_sprintf("slice of non-array type '%s'", buf_ptr(&array_type->name))); 18608 return ira->codegen->invalid_instruction; 18609 } 18610 18611 if (instr_is_comptime(ptr_ptr) && 18612 value_is_comptime(&casted_start->value) && 18613 (!end || value_is_comptime(&end->value))) 18614 { 18615 ConstExprValue *array_val; 18616 ConstExprValue *parent_ptr; 18617 size_t abs_offset; 18618 size_t rel_end; 18619 bool ptr_is_undef = false; 18620 if (array_type->id == ZigTypeIdArray || 18621 (array_type->id == ZigTypeIdPointer && array_type->data.pointer.ptr_len == PtrLenSingle)) 18622 { 18623 if (array_type->id == ZigTypeIdPointer) { 18624 ZigType *child_array_type = array_type->data.pointer.child_type; 18625 assert(child_array_type->id == ZigTypeIdArray); 18626 parent_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); 18627 if (parent_ptr == nullptr) 18628 return ira->codegen->invalid_instruction; 18629 18630 array_val = ir_const_ptr_pointee(ira, parent_ptr, instruction->base.source_node); 18631 if (array_val == nullptr) 18632 return ira->codegen->invalid_instruction; 18633 18634 rel_end = child_array_type->data.array.len; 18635 abs_offset = 0; 18636 } else { 18637 array_val = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); 18638 if (array_val == nullptr) 18639 return ira->codegen->invalid_instruction; 18640 rel_end = array_type->data.array.len; 18641 parent_ptr = nullptr; 18642 abs_offset = 0; 18643 } 18644 } else if (array_type->id == ZigTypeIdPointer) { 18645 assert(array_type->data.pointer.ptr_len == PtrLenUnknown); 18646 parent_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); 18647 if (parent_ptr == nullptr) 18648 return ira->codegen->invalid_instruction; 18649 18650 if (parent_ptr->special == ConstValSpecialUndef) { 18651 array_val = nullptr; 18652 abs_offset = 0; 18653 rel_end = SIZE_MAX; 18654 ptr_is_undef = true; 18655 } else switch (parent_ptr->data.x_ptr.special) { 18656 case ConstPtrSpecialInvalid: 18657 case ConstPtrSpecialDiscard: 18658 zig_unreachable(); 18659 case ConstPtrSpecialRef: 18660 if (parent_ptr->data.x_ptr.data.ref.pointee->type->id == ZigTypeIdArray) { 18661 array_val = parent_ptr->data.x_ptr.data.ref.pointee; 18662 abs_offset = 0; 18663 rel_end = array_val->type->data.array.len; 18664 } else { 18665 array_val = nullptr; 18666 abs_offset = SIZE_MAX; 18667 rel_end = 1; 18668 } 18669 break; 18670 case ConstPtrSpecialBaseArray: 18671 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 18672 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 18673 rel_end = array_val->type->data.array.len - abs_offset; 18674 break; 18675 case ConstPtrSpecialBaseStruct: 18676 zig_panic("TODO slice const inner struct"); 18677 case ConstPtrSpecialHardCodedAddr: 18678 array_val = nullptr; 18679 abs_offset = 0; 18680 rel_end = SIZE_MAX; 18681 break; 18682 case ConstPtrSpecialFunction: 18683 zig_panic("TODO slice of ptr cast from function"); 18684 } 18685 } else if (is_slice(array_type)) { 18686 ConstExprValue *slice_ptr = ir_const_ptr_pointee(ira, &ptr_ptr->value, instruction->base.source_node); 18687 if (slice_ptr == nullptr) 18688 return ira->codegen->invalid_instruction; 18689 18690 parent_ptr = &slice_ptr->data.x_struct.fields[slice_ptr_index]; 18691 if (parent_ptr->special == ConstValSpecialUndef) { 18692 ir_add_error(ira, &instruction->base, buf_sprintf("slice of undefined")); 18693 return ira->codegen->invalid_instruction; 18694 } 18695 18696 ConstExprValue *len_val = &slice_ptr->data.x_struct.fields[slice_len_index]; 18697 18698 switch (parent_ptr->data.x_ptr.special) { 18699 case ConstPtrSpecialInvalid: 18700 case ConstPtrSpecialDiscard: 18701 zig_unreachable(); 18702 case ConstPtrSpecialRef: 18703 array_val = nullptr; 18704 abs_offset = SIZE_MAX; 18705 rel_end = 1; 18706 break; 18707 case ConstPtrSpecialBaseArray: 18708 array_val = parent_ptr->data.x_ptr.data.base_array.array_val; 18709 abs_offset = parent_ptr->data.x_ptr.data.base_array.elem_index; 18710 rel_end = bigint_as_unsigned(&len_val->data.x_bigint); 18711 break; 18712 case ConstPtrSpecialBaseStruct: 18713 zig_panic("TODO slice const inner struct"); 18714 case ConstPtrSpecialHardCodedAddr: 18715 array_val = nullptr; 18716 abs_offset = 0; 18717 rel_end = bigint_as_unsigned(&len_val->data.x_bigint); 18718 break; 18719 case ConstPtrSpecialFunction: 18720 zig_panic("TODO slice of slice cast from function"); 18721 } 18722 } else { 18723 zig_unreachable(); 18724 } 18725 18726 uint64_t start_scalar = bigint_as_unsigned(&casted_start->value.data.x_bigint); 18727 if (!ptr_is_undef && start_scalar > rel_end) { 18728 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); 18729 return ira->codegen->invalid_instruction; 18730 } 18731 18732 uint64_t end_scalar; 18733 if (end) { 18734 end_scalar = bigint_as_unsigned(&end->value.data.x_bigint); 18735 } else { 18736 end_scalar = rel_end; 18737 } 18738 if (!ptr_is_undef) { 18739 if (end_scalar > rel_end) { 18740 ir_add_error(ira, &instruction->base, buf_sprintf("out of bounds slice")); 18741 return ira->codegen->invalid_instruction; 18742 } 18743 if (start_scalar > end_scalar) { 18744 ir_add_error(ira, &instruction->base, buf_sprintf("slice start is greater than end")); 18745 return ira->codegen->invalid_instruction; 18746 } 18747 } 18748 if (ptr_is_undef && start_scalar != end_scalar) { 18749 ir_add_error(ira, &instruction->base, buf_sprintf("non-zero length slice of undefined pointer")); 18750 return ira->codegen->invalid_instruction; 18751 } 18752 18753 IrInstruction *result = ir_const(ira, &instruction->base, return_type); 18754 ConstExprValue *out_val = &result->value; 18755 out_val->data.x_struct.fields = create_const_vals(2); 18756 18757 ConstExprValue *ptr_val = &out_val->data.x_struct.fields[slice_ptr_index]; 18758 18759 if (array_val) { 18760 size_t index = abs_offset + start_scalar; 18761 bool is_const = slice_is_const(return_type); 18762 init_const_ptr_array(ira->codegen, ptr_val, array_val, index, is_const, PtrLenUnknown); 18763 if (array_type->id == ZigTypeIdArray) { 18764 ptr_val->data.x_ptr.mut = ptr_ptr->value.data.x_ptr.mut; 18765 } else if (is_slice(array_type)) { 18766 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 18767 } else if (array_type->id == ZigTypeIdPointer) { 18768 ptr_val->data.x_ptr.mut = parent_ptr->data.x_ptr.mut; 18769 } 18770 } else if (ptr_is_undef) { 18771 ptr_val->type = get_pointer_to_type(ira->codegen, parent_ptr->type->data.pointer.child_type, 18772 slice_is_const(return_type)); 18773 ptr_val->special = ConstValSpecialUndef; 18774 } else switch (parent_ptr->data.x_ptr.special) { 18775 case ConstPtrSpecialInvalid: 18776 case ConstPtrSpecialDiscard: 18777 zig_unreachable(); 18778 case ConstPtrSpecialRef: 18779 init_const_ptr_ref(ira->codegen, ptr_val, 18780 parent_ptr->data.x_ptr.data.ref.pointee, slice_is_const(return_type)); 18781 break; 18782 case ConstPtrSpecialBaseArray: 18783 zig_unreachable(); 18784 case ConstPtrSpecialBaseStruct: 18785 zig_panic("TODO"); 18786 case ConstPtrSpecialHardCodedAddr: 18787 init_const_ptr_hard_coded_addr(ira->codegen, ptr_val, 18788 parent_ptr->type->data.pointer.child_type, 18789 parent_ptr->data.x_ptr.data.hard_coded_addr.addr + start_scalar, 18790 slice_is_const(return_type)); 18791 break; 18792 case ConstPtrSpecialFunction: 18793 zig_panic("TODO"); 18794 } 18795 18796 ConstExprValue *len_val = &out_val->data.x_struct.fields[slice_len_index]; 18797 init_const_usize(ira->codegen, len_val, end_scalar - start_scalar); 18798 18799 return result; 18800 } 18801 18802 IrInstruction *new_instruction = ir_build_slice(&ira->new_irb, 18803 instruction->base.scope, instruction->base.source_node, 18804 ptr_ptr, casted_start, end, instruction->safety_check_on); 18805 new_instruction->value.type = return_type; 18806 ir_add_alloca(ira, new_instruction, return_type); 18807 return new_instruction; 18808 } 18809 18810 static IrInstruction *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstructionMemberCount *instruction) { 18811 Error err; 18812 IrInstruction *container = instruction->container->child; 18813 if (type_is_invalid(container->value.type)) 18814 return ira->codegen->invalid_instruction; 18815 ZigType *container_type = ir_resolve_type(ira, container); 18816 18817 if ((err = ensure_complete_type(ira->codegen, container_type))) 18818 return ira->codegen->invalid_instruction; 18819 18820 uint64_t result; 18821 if (type_is_invalid(container_type)) { 18822 return ira->codegen->invalid_instruction; 18823 } else if (container_type->id == ZigTypeIdEnum) { 18824 result = container_type->data.enumeration.src_field_count; 18825 } else if (container_type->id == ZigTypeIdStruct) { 18826 result = container_type->data.structure.src_field_count; 18827 } else if (container_type->id == ZigTypeIdUnion) { 18828 result = container_type->data.unionation.src_field_count; 18829 } else if (container_type->id == ZigTypeIdErrorSet) { 18830 if (!resolve_inferred_error_set(ira->codegen, container_type, instruction->base.source_node)) { 18831 return ira->codegen->invalid_instruction; 18832 } 18833 if (type_is_global_error_set(container_type)) { 18834 ir_add_error(ira, &instruction->base, buf_sprintf("global error set member count not available at comptime")); 18835 return ira->codegen->invalid_instruction; 18836 } 18837 result = container_type->data.error_set.err_count; 18838 } else { 18839 ir_add_error(ira, &instruction->base, buf_sprintf("no value count available for type '%s'", buf_ptr(&container_type->name))); 18840 return ira->codegen->invalid_instruction; 18841 } 18842 18843 return ir_const_unsigned(ira, &instruction->base, result); 18844 } 18845 18846 static IrInstruction *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstructionMemberType *instruction) { 18847 Error err; 18848 IrInstruction *container_type_value = instruction->container_type->child; 18849 ZigType *container_type = ir_resolve_type(ira, container_type_value); 18850 if (type_is_invalid(container_type)) 18851 return ira->codegen->invalid_instruction; 18852 18853 if ((err = ensure_complete_type(ira->codegen, container_type))) 18854 return ira->codegen->invalid_instruction; 18855 18856 18857 uint64_t member_index; 18858 IrInstruction *index_value = instruction->member_index->child; 18859 if (!ir_resolve_usize(ira, index_value, &member_index)) 18860 return ira->codegen->invalid_instruction; 18861 18862 if (container_type->id == ZigTypeIdStruct) { 18863 if (member_index >= container_type->data.structure.src_field_count) { 18864 ir_add_error(ira, index_value, 18865 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 18866 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); 18867 return ira->codegen->invalid_instruction; 18868 } 18869 TypeStructField *field = &container_type->data.structure.fields[member_index]; 18870 18871 return ir_const_type(ira, &instruction->base, field->type_entry); 18872 } else if (container_type->id == ZigTypeIdUnion) { 18873 if (member_index >= container_type->data.unionation.src_field_count) { 18874 ir_add_error(ira, index_value, 18875 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 18876 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); 18877 return ira->codegen->invalid_instruction; 18878 } 18879 TypeUnionField *field = &container_type->data.unionation.fields[member_index]; 18880 18881 return ir_const_type(ira, &instruction->base, field->type_entry); 18882 } else { 18883 ir_add_error(ira, container_type_value, 18884 buf_sprintf("type '%s' does not support @memberType", buf_ptr(&container_type->name))); 18885 return ira->codegen->invalid_instruction; 18886 } 18887 } 18888 18889 static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstructionMemberName *instruction) { 18890 Error err; 18891 IrInstruction *container_type_value = instruction->container_type->child; 18892 ZigType *container_type = ir_resolve_type(ira, container_type_value); 18893 if (type_is_invalid(container_type)) 18894 return ira->codegen->invalid_instruction; 18895 18896 if ((err = ensure_complete_type(ira->codegen, container_type))) 18897 return ira->codegen->invalid_instruction; 18898 18899 uint64_t member_index; 18900 IrInstruction *index_value = instruction->member_index->child; 18901 if (!ir_resolve_usize(ira, index_value, &member_index)) 18902 return ira->codegen->invalid_instruction; 18903 18904 if (container_type->id == ZigTypeIdStruct) { 18905 if (member_index >= container_type->data.structure.src_field_count) { 18906 ir_add_error(ira, index_value, 18907 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 18908 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count)); 18909 return ira->codegen->invalid_instruction; 18910 } 18911 TypeStructField *field = &container_type->data.structure.fields[member_index]; 18912 18913 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 18914 init_const_str_lit(ira->codegen, &result->value, field->name); 18915 return result; 18916 } else if (container_type->id == ZigTypeIdEnum) { 18917 if (member_index >= container_type->data.enumeration.src_field_count) { 18918 ir_add_error(ira, index_value, 18919 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 18920 member_index, buf_ptr(&container_type->name), container_type->data.enumeration.src_field_count)); 18921 return ira->codegen->invalid_instruction; 18922 } 18923 TypeEnumField *field = &container_type->data.enumeration.fields[member_index]; 18924 18925 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 18926 init_const_str_lit(ira->codegen, &result->value, field->name); 18927 return result; 18928 } else if (container_type->id == ZigTypeIdUnion) { 18929 if (member_index >= container_type->data.unionation.src_field_count) { 18930 ir_add_error(ira, index_value, 18931 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members", 18932 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count)); 18933 return ira->codegen->invalid_instruction; 18934 } 18935 TypeUnionField *field = &container_type->data.unionation.fields[member_index]; 18936 18937 IrInstruction *result = ir_const(ira, &instruction->base, nullptr); 18938 init_const_str_lit(ira->codegen, &result->value, field->name); 18939 return result; 18940 } else { 18941 ir_add_error(ira, container_type_value, 18942 buf_sprintf("type '%s' does not support @memberName", buf_ptr(&container_type->name))); 18943 return ira->codegen->invalid_instruction; 18944 } 18945 } 18946 18947 static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) { 18948 IrInstruction *result = ir_build_breakpoint(&ira->new_irb, 18949 instruction->base.scope, instruction->base.source_node); 18950 result->value.type = ira->codegen->builtin_types.entry_void; 18951 return result; 18952 } 18953 18954 static IrInstruction *ir_analyze_instruction_return_address(IrAnalyze *ira, IrInstructionReturnAddress *instruction) { 18955 IrInstruction *result = ir_build_return_address(&ira->new_irb, 18956 instruction->base.scope, instruction->base.source_node); 18957 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 18958 ZigType *u8_ptr_const = get_pointer_to_type(ira->codegen, u8, true); 18959 result->value.type = u8_ptr_const; 18960 return result; 18961 } 18962 18963 static IrInstruction *ir_analyze_instruction_frame_address(IrAnalyze *ira, IrInstructionFrameAddress *instruction) { 18964 IrInstruction *result = ir_build_frame_address(&ira->new_irb, 18965 instruction->base.scope, instruction->base.source_node); 18966 ZigType *u8 = ira->codegen->builtin_types.entry_u8; 18967 ZigType *u8_ptr_const = get_pointer_to_type(ira->codegen, u8, true); 18968 result->value.type = u8_ptr_const; 18969 return result; 18970 } 18971 18972 static IrInstruction *ir_analyze_instruction_handle(IrAnalyze *ira, IrInstructionHandle *instruction) { 18973 IrInstruction *result = ir_build_handle(&ira->new_irb, instruction->base.scope, instruction->base.source_node); 18974 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 18975 assert(fn_entry != nullptr); 18976 result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type); 18977 return result; 18978 } 18979 18980 static IrInstruction *ir_analyze_instruction_align_of(IrAnalyze *ira, IrInstructionAlignOf *instruction) { 18981 Error err; 18982 IrInstruction *type_value = instruction->type_value->child; 18983 if (type_is_invalid(type_value->value.type)) 18984 return ira->codegen->invalid_instruction; 18985 ZigType *type_entry = ir_resolve_type(ira, type_value); 18986 18987 if ((err = type_resolve(ira->codegen, type_entry, ResolveStatusAlignmentKnown))) 18988 return ira->codegen->invalid_instruction; 18989 18990 switch (type_entry->id) { 18991 case ZigTypeIdInvalid: 18992 zig_unreachable(); 18993 case ZigTypeIdMetaType: 18994 case ZigTypeIdUnreachable: 18995 case ZigTypeIdComptimeFloat: 18996 case ZigTypeIdComptimeInt: 18997 case ZigTypeIdUndefined: 18998 case ZigTypeIdNull: 18999 case ZigTypeIdNamespace: 19000 case ZigTypeIdBoundFn: 19001 case ZigTypeIdArgTuple: 19002 case ZigTypeIdVoid: 19003 case ZigTypeIdOpaque: 19004 ir_add_error(ira, instruction->type_value, 19005 buf_sprintf("no align available for type '%s'", buf_ptr(&type_entry->name))); 19006 return ira->codegen->invalid_instruction; 19007 case ZigTypeIdBool: 19008 case ZigTypeIdInt: 19009 case ZigTypeIdFloat: 19010 case ZigTypeIdPointer: 19011 case ZigTypeIdPromise: 19012 case ZigTypeIdArray: 19013 case ZigTypeIdStruct: 19014 case ZigTypeIdOptional: 19015 case ZigTypeIdErrorUnion: 19016 case ZigTypeIdErrorSet: 19017 case ZigTypeIdEnum: 19018 case ZigTypeIdUnion: 19019 case ZigTypeIdFn: 19020 { 19021 uint64_t align_in_bytes = get_abi_alignment(ira->codegen, type_entry); 19022 return ir_const_unsigned(ira, &instruction->base, align_in_bytes); 19023 } 19024 } 19025 zig_unreachable(); 19026 } 19027 19028 static IrInstruction *ir_analyze_instruction_overflow_op(IrAnalyze *ira, IrInstructionOverflowOp *instruction) { 19029 Error err; 19030 19031 IrInstruction *type_value = instruction->type_value->child; 19032 if (type_is_invalid(type_value->value.type)) 19033 return ira->codegen->invalid_instruction; 19034 19035 ZigType *dest_type = ir_resolve_type(ira, type_value); 19036 if (type_is_invalid(dest_type)) 19037 return ira->codegen->invalid_instruction; 19038 19039 if (dest_type->id != ZigTypeIdInt) { 19040 ir_add_error(ira, type_value, 19041 buf_sprintf("expected integer type, found '%s'", buf_ptr(&dest_type->name))); 19042 return ira->codegen->invalid_instruction; 19043 } 19044 19045 IrInstruction *op1 = instruction->op1->child; 19046 if (type_is_invalid(op1->value.type)) 19047 return ira->codegen->invalid_instruction; 19048 19049 IrInstruction *casted_op1 = ir_implicit_cast(ira, op1, dest_type); 19050 if (type_is_invalid(casted_op1->value.type)) 19051 return ira->codegen->invalid_instruction; 19052 19053 IrInstruction *op2 = instruction->op2->child; 19054 if (type_is_invalid(op2->value.type)) 19055 return ira->codegen->invalid_instruction; 19056 19057 IrInstruction *casted_op2; 19058 if (instruction->op == IrOverflowOpShl) { 19059 ZigType *shift_amt_type = get_smallest_unsigned_int_type(ira->codegen, 19060 dest_type->data.integral.bit_count - 1); 19061 casted_op2 = ir_implicit_cast(ira, op2, shift_amt_type); 19062 } else { 19063 casted_op2 = ir_implicit_cast(ira, op2, dest_type); 19064 } 19065 if (type_is_invalid(casted_op2->value.type)) 19066 return ira->codegen->invalid_instruction; 19067 19068 IrInstruction *result_ptr = instruction->result_ptr->child; 19069 if (type_is_invalid(result_ptr->value.type)) 19070 return ira->codegen->invalid_instruction; 19071 19072 ZigType *expected_ptr_type; 19073 if (result_ptr->value.type->id == ZigTypeIdPointer) { 19074 uint32_t alignment; 19075 if ((err = resolve_ptr_align(ira, result_ptr->value.type, &alignment))) 19076 return ira->codegen->invalid_instruction; 19077 expected_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_type, 19078 false, result_ptr->value.type->data.pointer.is_volatile, 19079 PtrLenSingle, 19080 alignment, 0, 0); 19081 } else { 19082 expected_ptr_type = get_pointer_to_type(ira->codegen, dest_type, false); 19083 } 19084 19085 IrInstruction *casted_result_ptr = ir_implicit_cast(ira, result_ptr, expected_ptr_type); 19086 if (type_is_invalid(casted_result_ptr->value.type)) 19087 return ira->codegen->invalid_instruction; 19088 19089 if (casted_op1->value.special == ConstValSpecialStatic && 19090 casted_op2->value.special == ConstValSpecialStatic && 19091 casted_result_ptr->value.special == ConstValSpecialStatic) 19092 { 19093 BigInt *op1_bigint = &casted_op1->value.data.x_bigint; 19094 BigInt *op2_bigint = &casted_op2->value.data.x_bigint; 19095 ConstExprValue *pointee_val = ir_const_ptr_pointee(ira, &casted_result_ptr->value, casted_result_ptr->source_node); 19096 if (pointee_val == nullptr) 19097 return ira->codegen->invalid_instruction; 19098 BigInt *dest_bigint = &pointee_val->data.x_bigint; 19099 switch (instruction->op) { 19100 case IrOverflowOpAdd: 19101 bigint_add(dest_bigint, op1_bigint, op2_bigint); 19102 break; 19103 case IrOverflowOpSub: 19104 bigint_sub(dest_bigint, op1_bigint, op2_bigint); 19105 break; 19106 case IrOverflowOpMul: 19107 bigint_mul(dest_bigint, op1_bigint, op2_bigint); 19108 break; 19109 case IrOverflowOpShl: 19110 bigint_shl(dest_bigint, op1_bigint, op2_bigint); 19111 break; 19112 } 19113 bool result_bool = false; 19114 if (!bigint_fits_in_bits(dest_bigint, dest_type->data.integral.bit_count, 19115 dest_type->data.integral.is_signed)) 19116 { 19117 result_bool = true; 19118 BigInt tmp_bigint; 19119 bigint_init_bigint(&tmp_bigint, dest_bigint); 19120 bigint_truncate(dest_bigint, &tmp_bigint, dest_type->data.integral.bit_count, 19121 dest_type->data.integral.is_signed); 19122 } 19123 pointee_val->special = ConstValSpecialStatic; 19124 return ir_const_bool(ira, &instruction->base, result_bool); 19125 } 19126 19127 IrInstruction *result = ir_build_overflow_op(&ira->new_irb, 19128 instruction->base.scope, instruction->base.source_node, 19129 instruction->op, type_value, casted_op1, casted_op2, casted_result_ptr, dest_type); 19130 result->value.type = ira->codegen->builtin_types.entry_bool; 19131 return result; 19132 } 19133 19134 static IrInstruction *ir_analyze_instruction_test_err(IrAnalyze *ira, IrInstructionTestErr *instruction) { 19135 IrInstruction *value = instruction->value->child; 19136 if (type_is_invalid(value->value.type)) 19137 return ira->codegen->invalid_instruction; 19138 19139 ZigType *type_entry = value->value.type; 19140 if (type_is_invalid(type_entry)) { 19141 return ira->codegen->invalid_instruction; 19142 } else if (type_entry->id == ZigTypeIdErrorUnion) { 19143 if (instr_is_comptime(value)) { 19144 ConstExprValue *err_union_val = ir_resolve_const(ira, value, UndefBad); 19145 if (!err_union_val) 19146 return ira->codegen->invalid_instruction; 19147 19148 if (err_union_val->special != ConstValSpecialRuntime) { 19149 return ir_const_bool(ira, &instruction->base, (err_union_val->data.x_err_union.err != nullptr)); 19150 } 19151 } 19152 19153 ZigType *err_set_type = type_entry->data.error_union.err_set_type; 19154 if (!resolve_inferred_error_set(ira->codegen, err_set_type, instruction->base.source_node)) { 19155 return ira->codegen->invalid_instruction; 19156 } 19157 if (!type_is_global_error_set(err_set_type) && 19158 err_set_type->data.error_set.err_count == 0) 19159 { 19160 assert(err_set_type->data.error_set.infer_fn == nullptr); 19161 return ir_const_bool(ira, &instruction->base, false); 19162 } 19163 19164 IrInstruction *result = ir_build_test_err(&ira->new_irb, 19165 instruction->base.scope, instruction->base.source_node, value); 19166 result->value.type = ira->codegen->builtin_types.entry_bool; 19167 return result; 19168 } else if (type_entry->id == ZigTypeIdErrorSet) { 19169 return ir_const_bool(ira, &instruction->base, true); 19170 } else { 19171 return ir_const_bool(ira, &instruction->base, false); 19172 } 19173 } 19174 19175 static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, 19176 IrInstructionUnwrapErrCode *instruction) 19177 { 19178 IrInstruction *value = instruction->value->child; 19179 if (type_is_invalid(value->value.type)) 19180 return ira->codegen->invalid_instruction; 19181 ZigType *ptr_type = value->value.type; 19182 19183 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 19184 assert(ptr_type->id == ZigTypeIdPointer); 19185 19186 ZigType *type_entry = ptr_type->data.pointer.child_type; 19187 if (type_is_invalid(type_entry)) { 19188 return ira->codegen->invalid_instruction; 19189 } else if (type_entry->id == ZigTypeIdErrorUnion) { 19190 if (instr_is_comptime(value)) { 19191 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); 19192 if (!ptr_val) 19193 return ira->codegen->invalid_instruction; 19194 ConstExprValue *err_union_val = ir_const_ptr_pointee(ira, ptr_val, instruction->base.source_node); 19195 if (err_union_val == nullptr) 19196 return ira->codegen->invalid_instruction; 19197 if (err_union_val->special != ConstValSpecialRuntime) { 19198 ErrorTableEntry *err = err_union_val->data.x_err_union.err; 19199 assert(err); 19200 19201 IrInstruction *result = ir_const(ira, &instruction->base, 19202 type_entry->data.error_union.err_set_type); 19203 result->value.data.x_err_set = err; 19204 return result; 19205 } 19206 } 19207 19208 IrInstruction *result = ir_build_unwrap_err_code(&ira->new_irb, 19209 instruction->base.scope, instruction->base.source_node, value); 19210 result->value.type = type_entry->data.error_union.err_set_type; 19211 return result; 19212 } else { 19213 ir_add_error(ira, value, 19214 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 19215 return ira->codegen->invalid_instruction; 19216 } 19217 } 19218 19219 static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira, 19220 IrInstructionUnwrapErrPayload *instruction) 19221 { 19222 assert(instruction->value->child); 19223 IrInstruction *value = instruction->value->child; 19224 if (type_is_invalid(value->value.type)) 19225 return ira->codegen->invalid_instruction; 19226 ZigType *ptr_type = value->value.type; 19227 19228 // This will be a pointer type because unwrap err payload IR instruction operates on a pointer to a thing. 19229 assert(ptr_type->id == ZigTypeIdPointer); 19230 19231 ZigType *type_entry = ptr_type->data.pointer.child_type; 19232 if (type_is_invalid(type_entry)) { 19233 return ira->codegen->invalid_instruction; 19234 } else if (type_entry->id == ZigTypeIdErrorUnion) { 19235 ZigType *payload_type = type_entry->data.error_union.payload_type; 19236 if (type_is_invalid(payload_type)) { 19237 return ira->codegen->invalid_instruction; 19238 } 19239 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, payload_type, 19240 ptr_type->data.pointer.is_const, ptr_type->data.pointer.is_volatile, 19241 PtrLenSingle, 0, 0, 0); 19242 if (instr_is_comptime(value)) { 19243 ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad); 19244 if (!ptr_val) 19245 return ira->codegen->invalid_instruction; 19246 ConstExprValue *err_union_val = ir_const_ptr_pointee(ira, ptr_val, instruction->base.source_node); 19247 if (err_union_val == nullptr) 19248 return ira->codegen->invalid_instruction; 19249 if (err_union_val->special != ConstValSpecialRuntime) { 19250 ErrorTableEntry *err = err_union_val->data.x_err_union.err; 19251 if (err != nullptr) { 19252 ir_add_error(ira, &instruction->base, 19253 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name))); 19254 return ira->codegen->invalid_instruction; 19255 } 19256 19257 IrInstruction *result = ir_const(ira, &instruction->base, result_type); 19258 result->value.data.x_ptr.special = ConstPtrSpecialRef; 19259 result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload; 19260 return result; 19261 } 19262 } 19263 19264 IrInstruction *result = ir_build_unwrap_err_payload(&ira->new_irb, 19265 instruction->base.scope, instruction->base.source_node, value, instruction->safety_check_on); 19266 result->value.type = result_type; 19267 return result; 19268 } else { 19269 ir_add_error(ira, value, 19270 buf_sprintf("expected error union type, found '%s'", buf_ptr(&type_entry->name))); 19271 return ira->codegen->invalid_instruction; 19272 } 19273 19274 } 19275 19276 static IrInstruction *ir_analyze_instruction_fn_proto(IrAnalyze *ira, IrInstructionFnProto *instruction) { 19277 Error err; 19278 AstNode *proto_node = instruction->base.source_node; 19279 assert(proto_node->type == NodeTypeFnProto); 19280 19281 if (proto_node->data.fn_proto.auto_err_set) { 19282 ir_add_error(ira, &instruction->base, 19283 buf_sprintf("inferring error set of return type valid only for function definitions")); 19284 return ira->codegen->invalid_instruction; 19285 } 19286 19287 FnTypeId fn_type_id = {0}; 19288 init_fn_type_id(&fn_type_id, proto_node, proto_node->data.fn_proto.params.length); 19289 19290 for (; fn_type_id.next_param_index < fn_type_id.param_count; fn_type_id.next_param_index += 1) { 19291 AstNode *param_node = proto_node->data.fn_proto.params.at(fn_type_id.next_param_index); 19292 assert(param_node->type == NodeTypeParamDecl); 19293 19294 bool param_is_var_args = param_node->data.param_decl.is_var_args; 19295 if (param_is_var_args) { 19296 if (fn_type_id.cc == CallingConventionC) { 19297 fn_type_id.param_count = fn_type_id.next_param_index; 19298 continue; 19299 } else if (fn_type_id.cc == CallingConventionUnspecified) { 19300 return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); 19301 } else { 19302 zig_unreachable(); 19303 } 19304 } 19305 FnTypeParamInfo *param_info = &fn_type_id.param_info[fn_type_id.next_param_index]; 19306 param_info->is_noalias = param_node->data.param_decl.is_noalias; 19307 19308 if (instruction->param_types[fn_type_id.next_param_index] == nullptr) { 19309 param_info->type = nullptr; 19310 return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); 19311 } else { 19312 IrInstruction *param_type_value = instruction->param_types[fn_type_id.next_param_index]->child; 19313 if (type_is_invalid(param_type_value->value.type)) 19314 return ira->codegen->invalid_instruction; 19315 ZigType *param_type = ir_resolve_type(ira, param_type_value); 19316 if (type_is_invalid(param_type)) 19317 return ira->codegen->invalid_instruction; 19318 if ((err = type_resolve(ira->codegen, param_type, ResolveStatusZeroBitsKnown))) 19319 return ira->codegen->invalid_instruction; 19320 if (type_requires_comptime(param_type)) { 19321 if (!calling_convention_allows_zig_types(fn_type_id.cc)) { 19322 ir_add_error(ira, param_type_value, 19323 buf_sprintf("parameter of type '%s' not allowed in function with calling convention '%s'", 19324 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 19325 return ira->codegen->invalid_instruction; 19326 } 19327 param_info->type = param_type; 19328 fn_type_id.next_param_index += 1; 19329 return ir_const_type(ira, &instruction->base, get_generic_fn_type(ira->codegen, &fn_type_id)); 19330 } 19331 if (!type_has_bits(param_type) && !calling_convention_allows_zig_types(fn_type_id.cc)) { 19332 ir_add_error(ira, param_type_value, 19333 buf_sprintf("parameter of type '%s' has 0 bits; not allowed in function with calling convention '%s'", 19334 buf_ptr(¶m_type->name), calling_convention_name(fn_type_id.cc))); 19335 return ira->codegen->invalid_instruction; 19336 } 19337 param_info->type = param_type; 19338 } 19339 19340 } 19341 19342 if (instruction->align_value != nullptr) { 19343 if (!ir_resolve_align(ira, instruction->align_value->child, &fn_type_id.alignment)) 19344 return ira->codegen->invalid_instruction; 19345 } 19346 19347 IrInstruction *return_type_value = instruction->return_type->child; 19348 fn_type_id.return_type = ir_resolve_type(ira, return_type_value); 19349 if (type_is_invalid(fn_type_id.return_type)) 19350 return ira->codegen->invalid_instruction; 19351 if (fn_type_id.return_type->id == ZigTypeIdOpaque) { 19352 ir_add_error(ira, instruction->return_type, 19353 buf_sprintf("return type cannot be opaque")); 19354 return ira->codegen->invalid_instruction; 19355 } 19356 19357 if (fn_type_id.cc == CallingConventionAsync) { 19358 if (instruction->async_allocator_type_value == nullptr) { 19359 ir_add_error(ira, &instruction->base, 19360 buf_sprintf("async fn proto missing allocator type")); 19361 return ira->codegen->invalid_instruction; 19362 } 19363 IrInstruction *async_allocator_type_value = instruction->async_allocator_type_value->child; 19364 fn_type_id.async_allocator_type = ir_resolve_type(ira, async_allocator_type_value); 19365 if (type_is_invalid(fn_type_id.async_allocator_type)) 19366 return ira->codegen->invalid_instruction; 19367 } 19368 19369 return ir_const_type(ira, &instruction->base, get_fn_type(ira->codegen, &fn_type_id)); 19370 } 19371 19372 static IrInstruction *ir_analyze_instruction_test_comptime(IrAnalyze *ira, IrInstructionTestComptime *instruction) { 19373 IrInstruction *value = instruction->value->child; 19374 if (type_is_invalid(value->value.type)) 19375 return ira->codegen->invalid_instruction; 19376 19377 return ir_const_bool(ira, &instruction->base, instr_is_comptime(value)); 19378 } 19379 19380 static IrInstruction *ir_analyze_instruction_check_switch_prongs(IrAnalyze *ira, 19381 IrInstructionCheckSwitchProngs *instruction) 19382 { 19383 IrInstruction *target_value = instruction->target_value->child; 19384 ZigType *switch_type = target_value->value.type; 19385 if (type_is_invalid(switch_type)) 19386 return ira->codegen->invalid_instruction; 19387 19388 if (switch_type->id == ZigTypeIdEnum) { 19389 HashMap<BigInt, AstNode *, bigint_hash, bigint_eql> field_prev_uses = {}; 19390 field_prev_uses.init(switch_type->data.enumeration.src_field_count); 19391 19392 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 19393 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 19394 19395 IrInstruction *start_value = range->start->child; 19396 if (type_is_invalid(start_value->value.type)) 19397 return ira->codegen->invalid_instruction; 19398 19399 IrInstruction *end_value = range->end->child; 19400 if (type_is_invalid(end_value->value.type)) 19401 return ira->codegen->invalid_instruction; 19402 19403 if (start_value->value.type->id != ZigTypeIdEnum) { 19404 ir_add_error(ira, range->start, buf_sprintf("not an enum type")); 19405 return ira->codegen->invalid_instruction; 19406 } 19407 19408 BigInt start_index; 19409 bigint_init_bigint(&start_index, &start_value->value.data.x_enum_tag); 19410 19411 assert(end_value->value.type->id == ZigTypeIdEnum); 19412 BigInt end_index; 19413 bigint_init_bigint(&end_index, &end_value->value.data.x_enum_tag); 19414 19415 BigInt field_index; 19416 bigint_init_bigint(&field_index, &start_index); 19417 for (;;) { 19418 Cmp cmp = bigint_cmp(&field_index, &end_index); 19419 if (cmp == CmpGT) { 19420 break; 19421 } 19422 auto entry = field_prev_uses.put_unique(field_index, start_value->source_node); 19423 if (entry) { 19424 AstNode *prev_node = entry->value; 19425 TypeEnumField *enum_field = find_enum_field_by_tag(switch_type, &field_index); 19426 assert(enum_field != nullptr); 19427 ErrorMsg *msg = ir_add_error(ira, start_value, 19428 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), 19429 buf_ptr(enum_field->name))); 19430 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 19431 } 19432 bigint_incr(&field_index); 19433 } 19434 } 19435 if (!instruction->have_else_prong) { 19436 for (uint32_t i = 0; i < switch_type->data.enumeration.src_field_count; i += 1) { 19437 TypeEnumField *enum_field = &switch_type->data.enumeration.fields[i]; 19438 19439 auto entry = field_prev_uses.maybe_get(enum_field->value); 19440 if (!entry) { 19441 ir_add_error(ira, &instruction->base, 19442 buf_sprintf("enumeration value '%s.%s' not handled in switch", buf_ptr(&switch_type->name), 19443 buf_ptr(enum_field->name))); 19444 } 19445 } 19446 } 19447 } else if (switch_type->id == ZigTypeIdErrorSet) { 19448 if (!resolve_inferred_error_set(ira->codegen, switch_type, target_value->source_node)) { 19449 return ira->codegen->invalid_instruction; 19450 } 19451 19452 AstNode **field_prev_uses = allocate<AstNode *>(ira->codegen->errors_by_index.length); 19453 19454 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 19455 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 19456 19457 IrInstruction *start_value = range->start->child; 19458 if (type_is_invalid(start_value->value.type)) 19459 return ira->codegen->invalid_instruction; 19460 19461 IrInstruction *end_value = range->end->child; 19462 if (type_is_invalid(end_value->value.type)) 19463 return ira->codegen->invalid_instruction; 19464 19465 assert(start_value->value.type->id == ZigTypeIdErrorSet); 19466 uint32_t start_index = start_value->value.data.x_err_set->value; 19467 19468 assert(end_value->value.type->id == ZigTypeIdErrorSet); 19469 uint32_t end_index = end_value->value.data.x_err_set->value; 19470 19471 if (start_index != end_index) { 19472 ir_add_error(ira, end_value, buf_sprintf("ranges not allowed when switching on errors")); 19473 return ira->codegen->invalid_instruction; 19474 } 19475 19476 AstNode *prev_node = field_prev_uses[start_index]; 19477 if (prev_node != nullptr) { 19478 Buf *err_name = &ira->codegen->errors_by_index.at(start_index)->name; 19479 ErrorMsg *msg = ir_add_error(ira, start_value, 19480 buf_sprintf("duplicate switch value: '%s.%s'", buf_ptr(&switch_type->name), buf_ptr(err_name))); 19481 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("other value is here")); 19482 } 19483 field_prev_uses[start_index] = start_value->source_node; 19484 } 19485 if (!instruction->have_else_prong) { 19486 if (type_is_global_error_set(switch_type)) { 19487 ir_add_error(ira, &instruction->base, 19488 buf_sprintf("else prong required when switching on type 'error'")); 19489 return ira->codegen->invalid_instruction; 19490 } else { 19491 for (uint32_t i = 0; i < switch_type->data.error_set.err_count; i += 1) { 19492 ErrorTableEntry *err_entry = switch_type->data.error_set.errors[i]; 19493 19494 AstNode *prev_node = field_prev_uses[err_entry->value]; 19495 if (prev_node == nullptr) { 19496 ir_add_error(ira, &instruction->base, 19497 buf_sprintf("error.%s not handled in switch", buf_ptr(&err_entry->name))); 19498 } 19499 } 19500 } 19501 } 19502 19503 free(field_prev_uses); 19504 } else if (switch_type->id == ZigTypeIdInt) { 19505 RangeSet rs = {0}; 19506 for (size_t range_i = 0; range_i < instruction->range_count; range_i += 1) { 19507 IrInstructionCheckSwitchProngsRange *range = &instruction->ranges[range_i]; 19508 19509 IrInstruction *start_value = range->start->child; 19510 if (type_is_invalid(start_value->value.type)) 19511 return ira->codegen->invalid_instruction; 19512 IrInstruction *casted_start_value = ir_implicit_cast(ira, start_value, switch_type); 19513 if (type_is_invalid(casted_start_value->value.type)) 19514 return ira->codegen->invalid_instruction; 19515 19516 IrInstruction *end_value = range->end->child; 19517 if (type_is_invalid(end_value->value.type)) 19518 return ira->codegen->invalid_instruction; 19519 IrInstruction *casted_end_value = ir_implicit_cast(ira, end_value, switch_type); 19520 if (type_is_invalid(casted_end_value->value.type)) 19521 return ira->codegen->invalid_instruction; 19522 19523 ConstExprValue *start_val = ir_resolve_const(ira, casted_start_value, UndefBad); 19524 if (!start_val) 19525 return ira->codegen->invalid_instruction; 19526 19527 ConstExprValue *end_val = ir_resolve_const(ira, casted_end_value, UndefBad); 19528 if (!end_val) 19529 return ira->codegen->invalid_instruction; 19530 19531 assert(start_val->type->id == ZigTypeIdInt || start_val->type->id == ZigTypeIdComptimeInt); 19532 assert(end_val->type->id == ZigTypeIdInt || end_val->type->id == ZigTypeIdComptimeInt); 19533 AstNode *prev_node = rangeset_add_range(&rs, &start_val->data.x_bigint, &end_val->data.x_bigint, 19534 start_value->source_node); 19535 if (prev_node != nullptr) { 19536 ErrorMsg *msg = ir_add_error(ira, start_value, buf_sprintf("duplicate switch value")); 19537 add_error_note(ira->codegen, msg, prev_node, buf_sprintf("previous value is here")); 19538 return ira->codegen->invalid_instruction; 19539 } 19540 } 19541 if (!instruction->have_else_prong) { 19542 BigInt min_val; 19543 eval_min_max_value_int(ira->codegen, switch_type, &min_val, false); 19544 BigInt max_val; 19545 eval_min_max_value_int(ira->codegen, switch_type, &max_val, true); 19546 if (!rangeset_spans(&rs, &min_val, &max_val)) { 19547 ir_add_error(ira, &instruction->base, buf_sprintf("switch must handle all possibilities")); 19548 return ira->codegen->invalid_instruction; 19549 } 19550 } 19551 } else if (!instruction->have_else_prong) { 19552 ir_add_error(ira, &instruction->base, 19553 buf_sprintf("else prong required when switching on type '%s'", buf_ptr(&switch_type->name))); 19554 return ira->codegen->invalid_instruction; 19555 } 19556 return ir_const_void(ira, &instruction->base); 19557 } 19558 19559 static IrInstruction *ir_analyze_instruction_check_statement_is_void(IrAnalyze *ira, 19560 IrInstructionCheckStatementIsVoid *instruction) 19561 { 19562 IrInstruction *statement_value = instruction->statement_value->child; 19563 ZigType *statement_type = statement_value->value.type; 19564 if (type_is_invalid(statement_type)) 19565 return ira->codegen->invalid_instruction; 19566 19567 if (statement_type->id != ZigTypeIdVoid) { 19568 ir_add_error(ira, &instruction->base, buf_sprintf("expression value is ignored")); 19569 } 19570 19571 return ir_const_void(ira, &instruction->base); 19572 } 19573 19574 static IrInstruction *ir_analyze_instruction_panic(IrAnalyze *ira, IrInstructionPanic *instruction) { 19575 IrInstruction *msg = instruction->msg->child; 19576 if (type_is_invalid(msg->value.type)) 19577 return ir_unreach_error(ira); 19578 19579 if (ir_should_inline(ira->new_irb.exec, instruction->base.scope)) { 19580 ir_add_error(ira, &instruction->base, buf_sprintf("encountered @panic at compile-time")); 19581 return ir_unreach_error(ira); 19582 } 19583 19584 ZigType *u8_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8, 19585 true, false, PtrLenUnknown, 0, 0, 0); 19586 ZigType *str_type = get_slice_type(ira->codegen, u8_ptr_type); 19587 IrInstruction *casted_msg = ir_implicit_cast(ira, msg, str_type); 19588 if (type_is_invalid(casted_msg->value.type)) 19589 return ir_unreach_error(ira); 19590 19591 IrInstruction *new_instruction = ir_build_panic(&ira->new_irb, instruction->base.scope, 19592 instruction->base.source_node, casted_msg); 19593 return ir_finish_anal(ira, new_instruction); 19594 } 19595 19596 static IrInstruction *ir_align_cast(IrAnalyze *ira, IrInstruction *target, uint32_t align_bytes, bool safety_check_on) { 19597 Error err; 19598 19599 ZigType *target_type = target->value.type; 19600 assert(!type_is_invalid(target_type)); 19601 19602 ZigType *result_type; 19603 uint32_t old_align_bytes; 19604 19605 if (target_type->id == ZigTypeIdPointer) { 19606 result_type = adjust_ptr_align(ira->codegen, target_type, align_bytes); 19607 if ((err = resolve_ptr_align(ira, target_type, &old_align_bytes))) 19608 return ira->codegen->invalid_instruction; 19609 } else if (target_type->id == ZigTypeIdFn) { 19610 FnTypeId fn_type_id = target_type->data.fn.fn_type_id; 19611 old_align_bytes = fn_type_id.alignment; 19612 fn_type_id.alignment = align_bytes; 19613 result_type = get_fn_type(ira->codegen, &fn_type_id); 19614 } else if (target_type->id == ZigTypeIdOptional && 19615 target_type->data.maybe.child_type->id == ZigTypeIdPointer) 19616 { 19617 ZigType *ptr_type = target_type->data.maybe.child_type; 19618 if ((err = resolve_ptr_align(ira, ptr_type, &old_align_bytes))) 19619 return ira->codegen->invalid_instruction; 19620 ZigType *better_ptr_type = adjust_ptr_align(ira->codegen, ptr_type, align_bytes); 19621 19622 result_type = get_optional_type(ira->codegen, better_ptr_type); 19623 } else if (target_type->id == ZigTypeIdOptional && 19624 target_type->data.maybe.child_type->id == ZigTypeIdFn) 19625 { 19626 FnTypeId fn_type_id = target_type->data.maybe.child_type->data.fn.fn_type_id; 19627 old_align_bytes = fn_type_id.alignment; 19628 fn_type_id.alignment = align_bytes; 19629 ZigType *fn_type = get_fn_type(ira->codegen, &fn_type_id); 19630 result_type = get_optional_type(ira->codegen, fn_type); 19631 } else if (is_slice(target_type)) { 19632 ZigType *slice_ptr_type = target_type->data.structure.fields[slice_ptr_index].type_entry; 19633 if ((err = resolve_ptr_align(ira, slice_ptr_type, &old_align_bytes))) 19634 return ira->codegen->invalid_instruction; 19635 ZigType *result_ptr_type = adjust_ptr_align(ira->codegen, slice_ptr_type, align_bytes); 19636 result_type = get_slice_type(ira->codegen, result_ptr_type); 19637 } else { 19638 ir_add_error(ira, target, 19639 buf_sprintf("expected pointer or slice, found '%s'", buf_ptr(&target_type->name))); 19640 return ira->codegen->invalid_instruction; 19641 } 19642 19643 if (instr_is_comptime(target)) { 19644 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 19645 if (!val) 19646 return ira->codegen->invalid_instruction; 19647 19648 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr && 19649 val->data.x_ptr.data.hard_coded_addr.addr % align_bytes != 0) 19650 { 19651 ir_add_error(ira, target, 19652 buf_sprintf("pointer address 0x%" ZIG_PRI_x64 " is not aligned to %" PRIu32 " bytes", 19653 val->data.x_ptr.data.hard_coded_addr.addr, align_bytes)); 19654 return ira->codegen->invalid_instruction; 19655 } 19656 19657 IrInstruction *result = ir_create_const(&ira->new_irb, target->scope, target->source_node, result_type); 19658 copy_const_val(&result->value, val, false); 19659 result->value.type = result_type; 19660 return result; 19661 } 19662 19663 IrInstruction *result; 19664 if (safety_check_on && align_bytes > old_align_bytes && align_bytes != 1) { 19665 result = ir_build_align_cast(&ira->new_irb, target->scope, target->source_node, nullptr, target); 19666 } else { 19667 result = ir_build_cast(&ira->new_irb, target->scope, target->source_node, result_type, target, CastOpNoop); 19668 } 19669 result->value.type = result_type; 19670 return result; 19671 } 19672 19673 static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, 19674 ZigType *dest_type, IrInstruction *dest_type_src) 19675 { 19676 Error err; 19677 19678 ZigType *src_type = ptr->value.type; 19679 assert(!type_is_invalid(src_type)); 19680 19681 // We have a check for zero bits later so we use get_src_ptr_type to 19682 // validate src_type and dest_type. 19683 19684 if (get_src_ptr_type(src_type) == nullptr) { 19685 ir_add_error(ira, ptr, buf_sprintf("expected pointer, found '%s'", buf_ptr(&src_type->name))); 19686 return ira->codegen->invalid_instruction; 19687 } 19688 19689 if (get_src_ptr_type(dest_type) == nullptr) { 19690 ir_add_error(ira, dest_type_src, 19691 buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 19692 return ira->codegen->invalid_instruction; 19693 } 19694 19695 if (get_ptr_const(src_type) && !get_ptr_const(dest_type)) { 19696 ir_add_error(ira, source_instr, buf_sprintf("cast discards const qualifier")); 19697 return ira->codegen->invalid_instruction; 19698 } 19699 19700 if (instr_is_comptime(ptr)) { 19701 ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk); 19702 if (!val) 19703 return ira->codegen->invalid_instruction; 19704 19705 IrInstruction *result = ir_create_const(&ira->new_irb, source_instr->scope, source_instr->source_node, 19706 dest_type); 19707 copy_const_val(&result->value, val, false); 19708 result->value.type = dest_type; 19709 return result; 19710 } 19711 19712 uint32_t src_align_bytes; 19713 if ((err = resolve_ptr_align(ira, src_type, &src_align_bytes))) 19714 return ira->codegen->invalid_instruction; 19715 19716 uint32_t dest_align_bytes; 19717 if ((err = resolve_ptr_align(ira, dest_type, &dest_align_bytes))) 19718 return ira->codegen->invalid_instruction; 19719 19720 if (dest_align_bytes > src_align_bytes) { 19721 ErrorMsg *msg = ir_add_error(ira, source_instr, buf_sprintf("cast increases pointer alignment")); 19722 add_error_note(ira->codegen, msg, ptr->source_node, 19723 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&src_type->name), src_align_bytes)); 19724 add_error_note(ira->codegen, msg, dest_type_src->source_node, 19725 buf_sprintf("'%s' has alignment %" PRIu32, buf_ptr(&dest_type->name), dest_align_bytes)); 19726 return ira->codegen->invalid_instruction; 19727 } 19728 19729 IrInstruction *casted_ptr = ir_build_ptr_cast(&ira->new_irb, source_instr->scope, 19730 source_instr->source_node, nullptr, ptr); 19731 casted_ptr->value.type = dest_type; 19732 19733 if (type_has_bits(dest_type) && !type_has_bits(src_type)) { 19734 ErrorMsg *msg = ir_add_error(ira, source_instr, 19735 buf_sprintf("'%s' and '%s' do not have the same in-memory representation", 19736 buf_ptr(&src_type->name), buf_ptr(&dest_type->name))); 19737 add_error_note(ira->codegen, msg, ptr->source_node, 19738 buf_sprintf("'%s' has no in-memory bits", buf_ptr(&src_type->name))); 19739 add_error_note(ira->codegen, msg, dest_type_src->source_node, 19740 buf_sprintf("'%s' has in-memory bits", buf_ptr(&dest_type->name))); 19741 return ira->codegen->invalid_instruction; 19742 } 19743 19744 // Keep the bigger alignment, it can only help- 19745 // unless the target is zero bits. 19746 IrInstruction *result; 19747 if (src_align_bytes > dest_align_bytes && type_has_bits(dest_type)) { 19748 result = ir_align_cast(ira, casted_ptr, src_align_bytes, false); 19749 if (type_is_invalid(result->value.type)) 19750 return ira->codegen->invalid_instruction; 19751 } else { 19752 result = casted_ptr; 19753 } 19754 return result; 19755 } 19756 19757 static IrInstruction *ir_analyze_instruction_ptr_cast(IrAnalyze *ira, IrInstructionPtrCast *instruction) { 19758 IrInstruction *dest_type_value = instruction->dest_type->child; 19759 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 19760 if (type_is_invalid(dest_type)) 19761 return ira->codegen->invalid_instruction; 19762 19763 IrInstruction *ptr = instruction->ptr->child; 19764 ZigType *src_type = ptr->value.type; 19765 if (type_is_invalid(src_type)) 19766 return ira->codegen->invalid_instruction; 19767 19768 return ir_analyze_ptr_cast(ira, &instruction->base, ptr, dest_type, dest_type_value); 19769 } 19770 19771 static void buf_write_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) { 19772 assert(val->special == ConstValSpecialStatic); 19773 switch (val->type->id) { 19774 case ZigTypeIdInvalid: 19775 case ZigTypeIdMetaType: 19776 case ZigTypeIdOpaque: 19777 case ZigTypeIdBoundFn: 19778 case ZigTypeIdArgTuple: 19779 case ZigTypeIdNamespace: 19780 case ZigTypeIdUnreachable: 19781 case ZigTypeIdComptimeFloat: 19782 case ZigTypeIdComptimeInt: 19783 case ZigTypeIdUndefined: 19784 case ZigTypeIdNull: 19785 case ZigTypeIdPromise: 19786 zig_unreachable(); 19787 case ZigTypeIdVoid: 19788 return; 19789 case ZigTypeIdBool: 19790 buf[0] = val->data.x_bool ? 1 : 0; 19791 return; 19792 case ZigTypeIdInt: 19793 bigint_write_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 19794 codegen->is_big_endian); 19795 return; 19796 case ZigTypeIdEnum: 19797 bigint_write_twos_complement(&val->data.x_enum_tag, buf, 19798 val->type->data.enumeration.tag_int_type->data.integral.bit_count, 19799 codegen->is_big_endian); 19800 return; 19801 case ZigTypeIdFloat: 19802 float_write_ieee597(val, buf, codegen->is_big_endian); 19803 return; 19804 case ZigTypeIdPointer: 19805 if (val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 19806 BigInt bn; 19807 bigint_init_unsigned(&bn, val->data.x_ptr.data.hard_coded_addr.addr); 19808 bigint_write_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, codegen->is_big_endian); 19809 return; 19810 } else { 19811 zig_unreachable(); 19812 } 19813 case ZigTypeIdArray: 19814 { 19815 size_t buf_i = 0; 19816 // TODO optimize the buf case 19817 expand_undef_array(codegen, val); 19818 for (size_t elem_i = 0; elem_i < val->type->data.array.len; elem_i += 1) { 19819 ConstExprValue *elem = &val->data.x_array.data.s_none.elements[elem_i]; 19820 buf_write_value_bytes(codegen, &buf[buf_i], elem); 19821 buf_i += type_size(codegen, elem->type); 19822 } 19823 } 19824 return; 19825 case ZigTypeIdStruct: 19826 zig_panic("TODO buf_write_value_bytes struct type"); 19827 case ZigTypeIdOptional: 19828 zig_panic("TODO buf_write_value_bytes maybe type"); 19829 case ZigTypeIdErrorUnion: 19830 zig_panic("TODO buf_write_value_bytes error union"); 19831 case ZigTypeIdErrorSet: 19832 zig_panic("TODO buf_write_value_bytes pure error type"); 19833 case ZigTypeIdFn: 19834 zig_panic("TODO buf_write_value_bytes fn type"); 19835 case ZigTypeIdUnion: 19836 zig_panic("TODO buf_write_value_bytes union type"); 19837 } 19838 zig_unreachable(); 19839 } 19840 19841 static void buf_read_value_bytes(CodeGen *codegen, uint8_t *buf, ConstExprValue *val) { 19842 assert(val->special == ConstValSpecialStatic); 19843 switch (val->type->id) { 19844 case ZigTypeIdInvalid: 19845 case ZigTypeIdMetaType: 19846 case ZigTypeIdOpaque: 19847 case ZigTypeIdBoundFn: 19848 case ZigTypeIdArgTuple: 19849 case ZigTypeIdNamespace: 19850 case ZigTypeIdUnreachable: 19851 case ZigTypeIdComptimeFloat: 19852 case ZigTypeIdComptimeInt: 19853 case ZigTypeIdUndefined: 19854 case ZigTypeIdNull: 19855 case ZigTypeIdPromise: 19856 zig_unreachable(); 19857 case ZigTypeIdVoid: 19858 return; 19859 case ZigTypeIdBool: 19860 val->data.x_bool = (buf[0] != 0); 19861 return; 19862 case ZigTypeIdInt: 19863 bigint_read_twos_complement(&val->data.x_bigint, buf, val->type->data.integral.bit_count, 19864 codegen->is_big_endian, val->type->data.integral.is_signed); 19865 return; 19866 case ZigTypeIdFloat: 19867 float_read_ieee597(val, buf, codegen->is_big_endian); 19868 return; 19869 case ZigTypeIdPointer: 19870 { 19871 val->data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 19872 BigInt bn; 19873 bigint_read_twos_complement(&bn, buf, codegen->builtin_types.entry_usize->data.integral.bit_count, 19874 codegen->is_big_endian, false); 19875 val->data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&bn); 19876 return; 19877 } 19878 case ZigTypeIdArray: 19879 zig_panic("TODO buf_read_value_bytes array type"); 19880 case ZigTypeIdStruct: 19881 zig_panic("TODO buf_read_value_bytes struct type"); 19882 case ZigTypeIdOptional: 19883 zig_panic("TODO buf_read_value_bytes maybe type"); 19884 case ZigTypeIdErrorUnion: 19885 zig_panic("TODO buf_read_value_bytes error union"); 19886 case ZigTypeIdErrorSet: 19887 zig_panic("TODO buf_read_value_bytes pure error type"); 19888 case ZigTypeIdEnum: 19889 zig_panic("TODO buf_read_value_bytes enum type"); 19890 case ZigTypeIdFn: 19891 zig_panic("TODO buf_read_value_bytes fn type"); 19892 case ZigTypeIdUnion: 19893 zig_panic("TODO buf_read_value_bytes union type"); 19894 } 19895 zig_unreachable(); 19896 } 19897 19898 static IrInstruction *ir_analyze_instruction_bit_cast(IrAnalyze *ira, IrInstructionBitCast *instruction) { 19899 Error err; 19900 IrInstruction *dest_type_value = instruction->dest_type->child; 19901 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 19902 if (type_is_invalid(dest_type)) 19903 return ira->codegen->invalid_instruction; 19904 19905 IrInstruction *value = instruction->value->child; 19906 ZigType *src_type = value->value.type; 19907 if (type_is_invalid(src_type)) 19908 return ira->codegen->invalid_instruction; 19909 19910 if ((err = ensure_complete_type(ira->codegen, dest_type))) 19911 return ira->codegen->invalid_instruction; 19912 19913 if ((err = ensure_complete_type(ira->codegen, src_type))) 19914 return ira->codegen->invalid_instruction; 19915 19916 if (get_codegen_ptr_type(src_type) != nullptr) { 19917 ir_add_error(ira, value, 19918 buf_sprintf("unable to @bitCast from pointer type '%s'", buf_ptr(&src_type->name))); 19919 return ira->codegen->invalid_instruction; 19920 } 19921 19922 switch (src_type->id) { 19923 case ZigTypeIdInvalid: 19924 case ZigTypeIdMetaType: 19925 case ZigTypeIdOpaque: 19926 case ZigTypeIdBoundFn: 19927 case ZigTypeIdArgTuple: 19928 case ZigTypeIdNamespace: 19929 case ZigTypeIdUnreachable: 19930 case ZigTypeIdComptimeFloat: 19931 case ZigTypeIdComptimeInt: 19932 case ZigTypeIdUndefined: 19933 case ZigTypeIdNull: 19934 ir_add_error(ira, dest_type_value, 19935 buf_sprintf("unable to @bitCast from type '%s'", buf_ptr(&src_type->name))); 19936 return ira->codegen->invalid_instruction; 19937 default: 19938 break; 19939 } 19940 19941 if (get_codegen_ptr_type(dest_type) != nullptr) { 19942 ir_add_error(ira, dest_type_value, 19943 buf_sprintf("unable to @bitCast to pointer type '%s'", buf_ptr(&dest_type->name))); 19944 return ira->codegen->invalid_instruction; 19945 } 19946 19947 switch (dest_type->id) { 19948 case ZigTypeIdInvalid: 19949 case ZigTypeIdMetaType: 19950 case ZigTypeIdOpaque: 19951 case ZigTypeIdBoundFn: 19952 case ZigTypeIdArgTuple: 19953 case ZigTypeIdNamespace: 19954 case ZigTypeIdUnreachable: 19955 case ZigTypeIdComptimeFloat: 19956 case ZigTypeIdComptimeInt: 19957 case ZigTypeIdUndefined: 19958 case ZigTypeIdNull: 19959 ir_add_error(ira, dest_type_value, 19960 buf_sprintf("unable to @bitCast to type '%s'", buf_ptr(&dest_type->name))); 19961 return ira->codegen->invalid_instruction; 19962 default: 19963 break; 19964 } 19965 19966 uint64_t dest_size_bytes = type_size(ira->codegen, dest_type); 19967 uint64_t src_size_bytes = type_size(ira->codegen, src_type); 19968 if (dest_size_bytes != src_size_bytes) { 19969 ir_add_error(ira, &instruction->base, 19970 buf_sprintf("destination type '%s' has size %" ZIG_PRI_u64 " but source type '%s' has size %" ZIG_PRI_u64, 19971 buf_ptr(&dest_type->name), dest_size_bytes, 19972 buf_ptr(&src_type->name), src_size_bytes)); 19973 return ira->codegen->invalid_instruction; 19974 } 19975 19976 if (instr_is_comptime(value)) { 19977 ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); 19978 if (!val) 19979 return ira->codegen->invalid_instruction; 19980 19981 IrInstruction *result = ir_const(ira, &instruction->base, dest_type); 19982 uint8_t *buf = allocate_nonzero<uint8_t>(src_size_bytes); 19983 buf_write_value_bytes(ira->codegen, buf, val); 19984 buf_read_value_bytes(ira->codegen, buf, &result->value); 19985 return result; 19986 } 19987 19988 IrInstruction *result = ir_build_bit_cast(&ira->new_irb, instruction->base.scope, 19989 instruction->base.source_node, nullptr, value); 19990 result->value.type = dest_type; 19991 return result; 19992 } 19993 19994 static IrInstruction *ir_analyze_instruction_int_to_ptr(IrAnalyze *ira, IrInstructionIntToPtr *instruction) { 19995 Error err; 19996 IrInstruction *dest_type_value = instruction->dest_type->child; 19997 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 19998 if (type_is_invalid(dest_type)) 19999 return ira->codegen->invalid_instruction; 20000 20001 // We explicitly check for the size, so we can use get_src_ptr_type 20002 if (get_src_ptr_type(dest_type) == nullptr) { 20003 ir_add_error(ira, dest_type_value, buf_sprintf("expected pointer, found '%s'", buf_ptr(&dest_type->name))); 20004 return ira->codegen->invalid_instruction; 20005 } 20006 20007 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 20008 return ira->codegen->invalid_instruction; 20009 if (!type_has_bits(dest_type)) { 20010 ir_add_error(ira, dest_type_value, 20011 buf_sprintf("type '%s' has 0 bits and cannot store information", buf_ptr(&dest_type->name))); 20012 return ira->codegen->invalid_instruction; 20013 } 20014 20015 IrInstruction *target = instruction->target->child; 20016 if (type_is_invalid(target->value.type)) 20017 return ira->codegen->invalid_instruction; 20018 20019 IrInstruction *casted_int = ir_implicit_cast(ira, target, ira->codegen->builtin_types.entry_usize); 20020 if (type_is_invalid(casted_int->value.type)) 20021 return ira->codegen->invalid_instruction; 20022 20023 if (instr_is_comptime(casted_int)) { 20024 ConstExprValue *val = ir_resolve_const(ira, casted_int, UndefBad); 20025 if (!val) 20026 return ira->codegen->invalid_instruction; 20027 20028 IrInstruction *result = ir_const(ira, &instruction->base, dest_type); 20029 result->value.data.x_ptr.special = ConstPtrSpecialHardCodedAddr; 20030 result->value.data.x_ptr.data.hard_coded_addr.addr = bigint_as_unsigned(&val->data.x_bigint); 20031 return result; 20032 } 20033 20034 IrInstruction *result = ir_build_int_to_ptr(&ira->new_irb, instruction->base.scope, 20035 instruction->base.source_node, nullptr, casted_int); 20036 result->value.type = dest_type; 20037 return result; 20038 } 20039 20040 static IrInstruction *ir_analyze_instruction_decl_ref(IrAnalyze *ira, 20041 IrInstructionDeclRef *instruction) 20042 { 20043 Tld *tld = instruction->tld; 20044 LVal lval = instruction->lval; 20045 20046 resolve_top_level_decl(ira->codegen, tld, lval == LValPtr, instruction->base.source_node); 20047 if (tld->resolution == TldResolutionInvalid) 20048 return ira->codegen->invalid_instruction; 20049 20050 switch (tld->id) { 20051 case TldIdContainer: 20052 case TldIdCompTime: 20053 zig_unreachable(); 20054 case TldIdVar: 20055 { 20056 TldVar *tld_var = (TldVar *)tld; 20057 ZigVar *var = tld_var->var; 20058 20059 IrInstruction *var_ptr = ir_get_var_ptr(ira, &instruction->base, var); 20060 if (type_is_invalid(var_ptr->value.type)) 20061 return ira->codegen->invalid_instruction; 20062 20063 if (tld_var->extern_lib_name != nullptr) { 20064 add_link_lib_symbol(ira, tld_var->extern_lib_name, &var->name, instruction->base.source_node); 20065 } 20066 20067 if (lval == LValPtr) { 20068 return var_ptr; 20069 } else { 20070 return ir_get_deref(ira, &instruction->base, var_ptr); 20071 } 20072 } 20073 case TldIdFn: 20074 { 20075 TldFn *tld_fn = (TldFn *)tld; 20076 ZigFn *fn_entry = tld_fn->fn_entry; 20077 assert(fn_entry->type_entry); 20078 20079 if (tld_fn->extern_lib_name != nullptr) { 20080 add_link_lib_symbol(ira, tld_fn->extern_lib_name, &fn_entry->symbol_name, instruction->base.source_node); 20081 } 20082 20083 IrInstruction *ref_instruction = ir_create_const_fn(&ira->new_irb, instruction->base.scope, 20084 instruction->base.source_node, fn_entry); 20085 if (lval == LValPtr) { 20086 return ir_get_ref(ira, &instruction->base, ref_instruction, true, false); 20087 } else { 20088 return ref_instruction; 20089 } 20090 } 20091 } 20092 zig_unreachable(); 20093 } 20094 20095 static IrInstruction *ir_analyze_instruction_ptr_to_int(IrAnalyze *ira, IrInstructionPtrToInt *instruction) { 20096 IrInstruction *target = instruction->target->child; 20097 if (type_is_invalid(target->value.type)) 20098 return ira->codegen->invalid_instruction; 20099 20100 ZigType *usize = ira->codegen->builtin_types.entry_usize; 20101 20102 // We check size explicitly so we can use get_src_ptr_type here. 20103 if (get_src_ptr_type(target->value.type) == nullptr) { 20104 ir_add_error(ira, target, 20105 buf_sprintf("expected pointer, found '%s'", buf_ptr(&target->value.type->name))); 20106 return ira->codegen->invalid_instruction; 20107 } 20108 20109 if (!type_has_bits(target->value.type)) { 20110 ir_add_error(ira, target, 20111 buf_sprintf("pointer to size 0 type has no address")); 20112 return ira->codegen->invalid_instruction; 20113 } 20114 20115 if (instr_is_comptime(target)) { 20116 ConstExprValue *val = ir_resolve_const(ira, target, UndefBad); 20117 if (!val) 20118 return ira->codegen->invalid_instruction; 20119 if (val->type->id == ZigTypeIdPointer && val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { 20120 IrInstruction *result = ir_create_const(&ira->new_irb, instruction->base.scope, 20121 instruction->base.source_node, usize); 20122 bigint_init_unsigned(&result->value.data.x_bigint, val->data.x_ptr.data.hard_coded_addr.addr); 20123 result->value.type = usize; 20124 return result; 20125 } 20126 } 20127 20128 IrInstruction *result = ir_build_ptr_to_int(&ira->new_irb, instruction->base.scope, 20129 instruction->base.source_node, target); 20130 result->value.type = usize; 20131 return result; 20132 } 20133 20134 static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstructionPtrType *instruction) { 20135 Error err; 20136 ZigType *child_type = ir_resolve_type(ira, instruction->child_type->child); 20137 if (type_is_invalid(child_type)) 20138 return ira->codegen->invalid_instruction; 20139 20140 if (child_type->id == ZigTypeIdUnreachable) { 20141 ir_add_error(ira, &instruction->base, buf_sprintf("pointer to noreturn not allowed")); 20142 return ira->codegen->invalid_instruction; 20143 } else if (child_type->id == ZigTypeIdOpaque && instruction->ptr_len == PtrLenUnknown) { 20144 ir_add_error(ira, &instruction->base, buf_sprintf("unknown-length pointer to opaque")); 20145 return ira->codegen->invalid_instruction; 20146 } 20147 20148 uint32_t align_bytes; 20149 if (instruction->align_value != nullptr) { 20150 if (!ir_resolve_align(ira, instruction->align_value->child, &align_bytes)) 20151 return ira->codegen->invalid_instruction; 20152 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusAlignmentKnown))) 20153 return ira->codegen->invalid_instruction; 20154 } else { 20155 if ((err = type_resolve(ira->codegen, child_type, ResolveStatusZeroBitsKnown))) 20156 return ira->codegen->invalid_instruction; 20157 align_bytes = 0; 20158 } 20159 20160 ZigType *result_type = get_pointer_to_type_extra(ira->codegen, child_type, 20161 instruction->is_const, instruction->is_volatile, 20162 instruction->ptr_len, align_bytes, 20163 instruction->bit_offset_start, instruction->host_int_bytes); 20164 return ir_const_type(ira, &instruction->base, result_type); 20165 } 20166 20167 static IrInstruction *ir_analyze_instruction_align_cast(IrAnalyze *ira, IrInstructionAlignCast *instruction) { 20168 uint32_t align_bytes; 20169 IrInstruction *align_bytes_inst = instruction->align_bytes->child; 20170 if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes)) 20171 return ira->codegen->invalid_instruction; 20172 20173 IrInstruction *target = instruction->target->child; 20174 if (type_is_invalid(target->value.type)) 20175 return ira->codegen->invalid_instruction; 20176 20177 IrInstruction *result = ir_align_cast(ira, target, align_bytes, true); 20178 if (type_is_invalid(result->value.type)) 20179 return ira->codegen->invalid_instruction; 20180 20181 return result; 20182 } 20183 20184 static IrInstruction *ir_analyze_instruction_opaque_type(IrAnalyze *ira, IrInstructionOpaqueType *instruction) { 20185 Buf *name = get_anon_type_name(ira->codegen, ira->new_irb.exec, "opaque", instruction->base.source_node); 20186 ZigType *result_type = get_opaque_type(ira->codegen, instruction->base.scope, instruction->base.source_node, 20187 buf_ptr(name)); 20188 return ir_const_type(ira, &instruction->base, result_type); 20189 } 20190 20191 static IrInstruction *ir_analyze_instruction_set_align_stack(IrAnalyze *ira, IrInstructionSetAlignStack *instruction) { 20192 uint32_t align_bytes; 20193 IrInstruction *align_bytes_inst = instruction->align_bytes->child; 20194 if (!ir_resolve_align(ira, align_bytes_inst, &align_bytes)) 20195 return ira->codegen->invalid_instruction; 20196 20197 if (align_bytes > 256) { 20198 ir_add_error(ira, &instruction->base, buf_sprintf("attempt to @setAlignStack(%" PRIu32 "); maximum is 256", align_bytes)); 20199 return ira->codegen->invalid_instruction; 20200 } 20201 20202 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 20203 if (fn_entry == nullptr) { 20204 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack outside function")); 20205 return ira->codegen->invalid_instruction; 20206 } 20207 if (fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionNaked) { 20208 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in naked function")); 20209 return ira->codegen->invalid_instruction; 20210 } 20211 20212 if (fn_entry->fn_inline == FnInlineAlways) { 20213 ir_add_error(ira, &instruction->base, buf_sprintf("@setAlignStack in inline function")); 20214 return ira->codegen->invalid_instruction; 20215 } 20216 20217 if (fn_entry->set_alignstack_node != nullptr) { 20218 ErrorMsg *msg = ir_add_error_node(ira, instruction->base.source_node, 20219 buf_sprintf("alignstack set twice")); 20220 add_error_note(ira->codegen, msg, fn_entry->set_alignstack_node, buf_sprintf("first set here")); 20221 return ira->codegen->invalid_instruction; 20222 } 20223 20224 fn_entry->set_alignstack_node = instruction->base.source_node; 20225 fn_entry->alignstack_value = align_bytes; 20226 20227 return ir_const_void(ira, &instruction->base); 20228 } 20229 20230 static IrInstruction *ir_analyze_instruction_arg_type(IrAnalyze *ira, IrInstructionArgType *instruction) { 20231 IrInstruction *fn_type_inst = instruction->fn_type->child; 20232 ZigType *fn_type = ir_resolve_type(ira, fn_type_inst); 20233 if (type_is_invalid(fn_type)) 20234 return ira->codegen->invalid_instruction; 20235 20236 IrInstruction *arg_index_inst = instruction->arg_index->child; 20237 uint64_t arg_index; 20238 if (!ir_resolve_usize(ira, arg_index_inst, &arg_index)) 20239 return ira->codegen->invalid_instruction; 20240 20241 if (fn_type->id != ZigTypeIdFn) { 20242 ir_add_error(ira, fn_type_inst, buf_sprintf("expected function, found '%s'", buf_ptr(&fn_type->name))); 20243 return ira->codegen->invalid_instruction; 20244 } 20245 20246 FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; 20247 if (arg_index >= fn_type_id->param_count) { 20248 ir_add_error(ira, arg_index_inst, 20249 buf_sprintf("arg index %" ZIG_PRI_u64 " out of bounds; '%s' has %" ZIG_PRI_usize " arguments", 20250 arg_index, buf_ptr(&fn_type->name), fn_type_id->param_count)); 20251 return ira->codegen->invalid_instruction; 20252 } 20253 20254 ZigType *result_type = fn_type_id->param_info[arg_index].type; 20255 if (result_type == nullptr) { 20256 // Args are only unresolved if our function is generic. 20257 assert(fn_type->data.fn.is_generic); 20258 20259 ir_add_error(ira, arg_index_inst, 20260 buf_sprintf("@ArgType could not resolve the type of arg %" ZIG_PRI_u64 " because '%s' is generic", 20261 arg_index, buf_ptr(&fn_type->name))); 20262 return ira->codegen->invalid_instruction; 20263 } 20264 return ir_const_type(ira, &instruction->base, result_type); 20265 } 20266 20267 static IrInstruction *ir_analyze_instruction_tag_type(IrAnalyze *ira, IrInstructionTagType *instruction) { 20268 Error err; 20269 IrInstruction *target_inst = instruction->target->child; 20270 ZigType *enum_type = ir_resolve_type(ira, target_inst); 20271 if (type_is_invalid(enum_type)) 20272 return ira->codegen->invalid_instruction; 20273 20274 if (enum_type->id == ZigTypeIdEnum) { 20275 if ((err = ensure_complete_type(ira->codegen, enum_type))) 20276 return ira->codegen->invalid_instruction; 20277 20278 return ir_const_type(ira, &instruction->base, enum_type->data.enumeration.tag_int_type); 20279 } else if (enum_type->id == ZigTypeIdUnion) { 20280 if ((err = ensure_complete_type(ira->codegen, enum_type))) 20281 return ira->codegen->invalid_instruction; 20282 20283 AstNode *decl_node = enum_type->data.unionation.decl_node; 20284 if (decl_node->data.container_decl.auto_enum || decl_node->data.container_decl.init_arg_expr != nullptr) { 20285 assert(enum_type->data.unionation.tag_type != nullptr); 20286 20287 return ir_const_type(ira, &instruction->base, enum_type->data.unionation.tag_type); 20288 } else { 20289 ErrorMsg *msg = ir_add_error(ira, target_inst, buf_sprintf("union '%s' has no tag", 20290 buf_ptr(&enum_type->name))); 20291 add_error_note(ira->codegen, msg, decl_node, buf_sprintf("consider 'union(enum)' here")); 20292 return ira->codegen->invalid_instruction; 20293 } 20294 } else { 20295 ir_add_error(ira, target_inst, buf_sprintf("expected enum or union, found '%s'", 20296 buf_ptr(&enum_type->name))); 20297 return ira->codegen->invalid_instruction; 20298 } 20299 } 20300 20301 static IrInstruction *ir_analyze_instruction_cancel(IrAnalyze *ira, IrInstructionCancel *instruction) { 20302 IrInstruction *target_inst = instruction->target->child; 20303 if (type_is_invalid(target_inst->value.type)) 20304 return ira->codegen->invalid_instruction; 20305 IrInstruction *casted_target = ir_implicit_cast(ira, target_inst, ira->codegen->builtin_types.entry_promise); 20306 if (type_is_invalid(casted_target->value.type)) 20307 return ira->codegen->invalid_instruction; 20308 20309 IrInstruction *result = ir_build_cancel(&ira->new_irb, instruction->base.scope, instruction->base.source_node, casted_target); 20310 result->value.type = ira->codegen->builtin_types.entry_void; 20311 result->value.special = ConstValSpecialStatic; 20312 return result; 20313 } 20314 20315 static IrInstruction *ir_analyze_instruction_coro_id(IrAnalyze *ira, IrInstructionCoroId *instruction) { 20316 IrInstruction *promise_ptr = instruction->promise_ptr->child; 20317 if (type_is_invalid(promise_ptr->value.type)) 20318 return ira->codegen->invalid_instruction; 20319 20320 IrInstruction *result = ir_build_coro_id(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 20321 promise_ptr); 20322 result->value.type = ira->codegen->builtin_types.entry_usize; 20323 return result; 20324 } 20325 20326 static IrInstruction *ir_analyze_instruction_coro_alloc(IrAnalyze *ira, IrInstructionCoroAlloc *instruction) { 20327 IrInstruction *coro_id = instruction->coro_id->child; 20328 if (type_is_invalid(coro_id->value.type)) 20329 return ira->codegen->invalid_instruction; 20330 20331 IrInstruction *result = ir_build_coro_alloc(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 20332 coro_id); 20333 result->value.type = ira->codegen->builtin_types.entry_bool; 20334 return result; 20335 } 20336 20337 static IrInstruction *ir_analyze_instruction_coro_size(IrAnalyze *ira, IrInstructionCoroSize *instruction) { 20338 IrInstruction *result = ir_build_coro_size(&ira->new_irb, instruction->base.scope, instruction->base.source_node); 20339 result->value.type = ira->codegen->builtin_types.entry_usize; 20340 return result; 20341 } 20342 20343 static IrInstruction *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstructionCoroBegin *instruction) { 20344 IrInstruction *coro_id = instruction->coro_id->child; 20345 if (type_is_invalid(coro_id->value.type)) 20346 return ira->codegen->invalid_instruction; 20347 20348 IrInstruction *coro_mem_ptr = instruction->coro_mem_ptr->child; 20349 if (type_is_invalid(coro_mem_ptr->value.type)) 20350 return ira->codegen->invalid_instruction; 20351 20352 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 20353 assert(fn_entry != nullptr); 20354 IrInstruction *result = ir_build_coro_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node, 20355 coro_id, coro_mem_ptr); 20356 result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type); 20357 return result; 20358 } 20359 20360 static IrInstruction *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) { 20361 return ir_get_implicit_allocator(ira, &instruction->base, instruction->id); 20362 } 20363 20364 static IrInstruction *ir_analyze_instruction_coro_alloc_fail(IrAnalyze *ira, IrInstructionCoroAllocFail *instruction) { 20365 IrInstruction *err_val = instruction->err_val->child; 20366 if (type_is_invalid(err_val->value.type)) 20367 return ir_unreach_error(ira); 20368 20369 IrInstruction *result = ir_build_coro_alloc_fail(&ira->new_irb, instruction->base.scope, instruction->base.source_node, err_val); 20370 result->value.type = ira->codegen->builtin_types.entry_unreachable; 20371 return ir_finish_anal(ira, result); 20372 } 20373 20374 static IrInstruction *ir_analyze_instruction_coro_suspend(IrAnalyze *ira, IrInstructionCoroSuspend *instruction) { 20375 IrInstruction *save_point = nullptr; 20376 if (instruction->save_point != nullptr) { 20377 save_point = instruction->save_point->child; 20378 if (type_is_invalid(save_point->value.type)) 20379 return ira->codegen->invalid_instruction; 20380 } 20381 20382 IrInstruction *is_final = instruction->is_final->child; 20383 if (type_is_invalid(is_final->value.type)) 20384 return ira->codegen->invalid_instruction; 20385 20386 IrInstruction *result = ir_build_coro_suspend(&ira->new_irb, instruction->base.scope, 20387 instruction->base.source_node, save_point, is_final); 20388 result->value.type = ira->codegen->builtin_types.entry_u8; 20389 return result; 20390 } 20391 20392 static IrInstruction *ir_analyze_instruction_coro_end(IrAnalyze *ira, IrInstructionCoroEnd *instruction) { 20393 IrInstruction *result = ir_build_coro_end(&ira->new_irb, instruction->base.scope, 20394 instruction->base.source_node); 20395 result->value.type = ira->codegen->builtin_types.entry_void; 20396 return result; 20397 } 20398 20399 static IrInstruction *ir_analyze_instruction_coro_free(IrAnalyze *ira, IrInstructionCoroFree *instruction) { 20400 IrInstruction *coro_id = instruction->coro_id->child; 20401 if (type_is_invalid(coro_id->value.type)) 20402 return ira->codegen->invalid_instruction; 20403 20404 IrInstruction *coro_handle = instruction->coro_handle->child; 20405 if (type_is_invalid(coro_handle->value.type)) 20406 return ira->codegen->invalid_instruction; 20407 20408 IrInstruction *result = ir_build_coro_free(&ira->new_irb, instruction->base.scope, 20409 instruction->base.source_node, coro_id, coro_handle); 20410 ZigType *ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false); 20411 result->value.type = get_optional_type(ira->codegen, ptr_type); 20412 return result; 20413 } 20414 20415 static IrInstruction *ir_analyze_instruction_coro_resume(IrAnalyze *ira, IrInstructionCoroResume *instruction) { 20416 IrInstruction *awaiter_handle = instruction->awaiter_handle->child; 20417 if (type_is_invalid(awaiter_handle->value.type)) 20418 return ira->codegen->invalid_instruction; 20419 20420 IrInstruction *casted_target = ir_implicit_cast(ira, awaiter_handle, ira->codegen->builtin_types.entry_promise); 20421 if (type_is_invalid(casted_target->value.type)) 20422 return ira->codegen->invalid_instruction; 20423 20424 IrInstruction *result = ir_build_coro_resume(&ira->new_irb, instruction->base.scope, 20425 instruction->base.source_node, casted_target); 20426 result->value.type = ira->codegen->builtin_types.entry_void; 20427 return result; 20428 } 20429 20430 static IrInstruction *ir_analyze_instruction_coro_save(IrAnalyze *ira, IrInstructionCoroSave *instruction) { 20431 IrInstruction *coro_handle = instruction->coro_handle->child; 20432 if (type_is_invalid(coro_handle->value.type)) 20433 return ira->codegen->invalid_instruction; 20434 20435 IrInstruction *result = ir_build_coro_save(&ira->new_irb, instruction->base.scope, 20436 instruction->base.source_node, coro_handle); 20437 result->value.type = ira->codegen->builtin_types.entry_usize; 20438 return result; 20439 } 20440 20441 static IrInstruction *ir_analyze_instruction_coro_promise(IrAnalyze *ira, IrInstructionCoroPromise *instruction) { 20442 IrInstruction *coro_handle = instruction->coro_handle->child; 20443 if (type_is_invalid(coro_handle->value.type)) 20444 return ira->codegen->invalid_instruction; 20445 20446 if (coro_handle->value.type->id != ZigTypeIdPromise || 20447 coro_handle->value.type->data.promise.result_type == nullptr) 20448 { 20449 ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'", 20450 buf_ptr(&coro_handle->value.type->name))); 20451 return ira->codegen->invalid_instruction; 20452 } 20453 20454 ZigType *coro_frame_type = get_promise_frame_type(ira->codegen, 20455 coro_handle->value.type->data.promise.result_type); 20456 20457 IrInstruction *result = ir_build_coro_promise(&ira->new_irb, instruction->base.scope, 20458 instruction->base.source_node, coro_handle); 20459 result->value.type = get_pointer_to_type(ira->codegen, coro_frame_type, false); 20460 return result; 20461 } 20462 20463 static IrInstruction *ir_analyze_instruction_coro_alloc_helper(IrAnalyze *ira, IrInstructionCoroAllocHelper *instruction) { 20464 IrInstruction *alloc_fn = instruction->alloc_fn->child; 20465 if (type_is_invalid(alloc_fn->value.type)) 20466 return ira->codegen->invalid_instruction; 20467 20468 IrInstruction *coro_size = instruction->coro_size->child; 20469 if (type_is_invalid(coro_size->value.type)) 20470 return ira->codegen->invalid_instruction; 20471 20472 IrInstruction *result = ir_build_coro_alloc_helper(&ira->new_irb, instruction->base.scope, 20473 instruction->base.source_node, alloc_fn, coro_size); 20474 ZigType *u8_ptr_type = get_pointer_to_type(ira->codegen, ira->codegen->builtin_types.entry_u8, false); 20475 result->value.type = get_optional_type(ira->codegen, u8_ptr_type); 20476 return result; 20477 } 20478 20479 static ZigType *ir_resolve_atomic_operand_type(IrAnalyze *ira, IrInstruction *op) { 20480 ZigType *operand_type = ir_resolve_type(ira, op); 20481 if (type_is_invalid(operand_type)) 20482 return ira->codegen->builtin_types.entry_invalid; 20483 20484 if (operand_type->id == ZigTypeIdInt) { 20485 if (operand_type->data.integral.bit_count < 8) { 20486 ir_add_error(ira, op, 20487 buf_sprintf("expected integer type 8 bits or larger, found %" PRIu32 "-bit integer type", 20488 operand_type->data.integral.bit_count)); 20489 return ira->codegen->builtin_types.entry_invalid; 20490 } 20491 if (operand_type->data.integral.bit_count > ira->codegen->pointer_size_bytes * 8) { 20492 ir_add_error(ira, op, 20493 buf_sprintf("expected integer type pointer size or smaller, found %" PRIu32 "-bit integer type", 20494 operand_type->data.integral.bit_count)); 20495 return ira->codegen->builtin_types.entry_invalid; 20496 } 20497 if (!is_power_of_2(operand_type->data.integral.bit_count)) { 20498 ir_add_error(ira, op, 20499 buf_sprintf("%" PRIu32 "-bit integer type is not a power of 2", operand_type->data.integral.bit_count)); 20500 return ira->codegen->builtin_types.entry_invalid; 20501 } 20502 } else if (get_codegen_ptr_type(operand_type) == nullptr) { 20503 ir_add_error(ira, op, 20504 buf_sprintf("expected integer or pointer type, found '%s'", buf_ptr(&operand_type->name))); 20505 return ira->codegen->builtin_types.entry_invalid; 20506 } 20507 20508 return operand_type; 20509 } 20510 20511 static IrInstruction *ir_analyze_instruction_atomic_rmw(IrAnalyze *ira, IrInstructionAtomicRmw *instruction) { 20512 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 20513 if (type_is_invalid(operand_type)) 20514 return ira->codegen->invalid_instruction; 20515 20516 IrInstruction *ptr_inst = instruction->ptr->child; 20517 if (type_is_invalid(ptr_inst->value.type)) 20518 return ira->codegen->invalid_instruction; 20519 20520 // TODO let this be volatile 20521 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, false); 20522 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 20523 if (type_is_invalid(casted_ptr->value.type)) 20524 return ira->codegen->invalid_instruction; 20525 20526 AtomicRmwOp op; 20527 if (instruction->op == nullptr) { 20528 op = instruction->resolved_op; 20529 } else { 20530 if (!ir_resolve_atomic_rmw_op(ira, instruction->op->child, &op)) { 20531 return ira->codegen->invalid_instruction; 20532 } 20533 } 20534 20535 IrInstruction *operand = instruction->operand->child; 20536 if (type_is_invalid(operand->value.type)) 20537 return ira->codegen->invalid_instruction; 20538 20539 IrInstruction *casted_operand = ir_implicit_cast(ira, operand, operand_type); 20540 if (type_is_invalid(casted_operand->value.type)) 20541 return ira->codegen->invalid_instruction; 20542 20543 AtomicOrder ordering; 20544 if (instruction->ordering == nullptr) { 20545 ordering = instruction->resolved_ordering; 20546 } else { 20547 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 20548 return ira->codegen->invalid_instruction; 20549 if (ordering == AtomicOrderUnordered) { 20550 ir_add_error(ira, instruction->ordering, 20551 buf_sprintf("@atomicRmw atomic ordering must not be Unordered")); 20552 return ira->codegen->invalid_instruction; 20553 } 20554 } 20555 20556 if (instr_is_comptime(casted_operand) && instr_is_comptime(casted_ptr) && casted_ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar) 20557 { 20558 zig_panic("TODO compile-time execution of atomicRmw"); 20559 } 20560 20561 IrInstruction *result = ir_build_atomic_rmw(&ira->new_irb, instruction->base.scope, 20562 instruction->base.source_node, nullptr, casted_ptr, nullptr, casted_operand, nullptr, 20563 op, ordering); 20564 result->value.type = operand_type; 20565 return result; 20566 } 20567 20568 static IrInstruction *ir_analyze_instruction_atomic_load(IrAnalyze *ira, IrInstructionAtomicLoad *instruction) { 20569 ZigType *operand_type = ir_resolve_atomic_operand_type(ira, instruction->operand_type->child); 20570 if (type_is_invalid(operand_type)) 20571 return ira->codegen->invalid_instruction; 20572 20573 IrInstruction *ptr_inst = instruction->ptr->child; 20574 if (type_is_invalid(ptr_inst->value.type)) 20575 return ira->codegen->invalid_instruction; 20576 20577 ZigType *ptr_type = get_pointer_to_type(ira->codegen, operand_type, true); 20578 IrInstruction *casted_ptr = ir_implicit_cast(ira, ptr_inst, ptr_type); 20579 if (type_is_invalid(casted_ptr->value.type)) 20580 return ira->codegen->invalid_instruction; 20581 20582 AtomicOrder ordering; 20583 if (instruction->ordering == nullptr) { 20584 ordering = instruction->resolved_ordering; 20585 } else { 20586 if (!ir_resolve_atomic_order(ira, instruction->ordering->child, &ordering)) 20587 return ira->codegen->invalid_instruction; 20588 } 20589 20590 if (ordering == AtomicOrderRelease || ordering == AtomicOrderAcqRel) { 20591 assert(instruction->ordering != nullptr); 20592 ir_add_error(ira, instruction->ordering, 20593 buf_sprintf("@atomicLoad atomic ordering must not be Release or AcqRel")); 20594 return ira->codegen->invalid_instruction; 20595 } 20596 20597 if (instr_is_comptime(casted_ptr)) { 20598 IrInstruction *result = ir_get_deref(ira, &instruction->base, casted_ptr); 20599 assert(result->value.type != nullptr); 20600 return result; 20601 } 20602 20603 IrInstruction *result = ir_build_atomic_load(&ira->new_irb, instruction->base.scope, 20604 instruction->base.source_node, nullptr, casted_ptr, nullptr, ordering); 20605 result->value.type = operand_type; 20606 return result; 20607 } 20608 20609 static IrInstruction *ir_analyze_instruction_promise_result_type(IrAnalyze *ira, IrInstructionPromiseResultType *instruction) { 20610 ZigType *promise_type = ir_resolve_type(ira, instruction->promise_type->child); 20611 if (type_is_invalid(promise_type)) 20612 return ira->codegen->invalid_instruction; 20613 20614 if (promise_type->id != ZigTypeIdPromise || promise_type->data.promise.result_type == nullptr) { 20615 ir_add_error(ira, &instruction->base, buf_sprintf("expected promise->T, found '%s'", 20616 buf_ptr(&promise_type->name))); 20617 return ira->codegen->invalid_instruction; 20618 } 20619 20620 return ir_const_type(ira, &instruction->base, promise_type->data.promise.result_type); 20621 } 20622 20623 static IrInstruction *ir_analyze_instruction_await_bookkeeping(IrAnalyze *ira, IrInstructionAwaitBookkeeping *instruction) { 20624 ZigType *promise_result_type = ir_resolve_type(ira, instruction->promise_result_type->child); 20625 if (type_is_invalid(promise_result_type)) 20626 return ira->codegen->invalid_instruction; 20627 20628 ZigFn *fn_entry = exec_fn_entry(ira->new_irb.exec); 20629 assert(fn_entry != nullptr); 20630 20631 if (type_can_fail(promise_result_type)) { 20632 fn_entry->calls_or_awaits_errorable_fn = true; 20633 } 20634 20635 return ir_const_void(ira, &instruction->base); 20636 } 20637 20638 static IrInstruction *ir_analyze_instruction_merge_err_ret_traces(IrAnalyze *ira, 20639 IrInstructionMergeErrRetTraces *instruction) 20640 { 20641 IrInstruction *coro_promise_ptr = instruction->coro_promise_ptr->child; 20642 if (type_is_invalid(coro_promise_ptr->value.type)) 20643 return ira->codegen->invalid_instruction; 20644 20645 assert(coro_promise_ptr->value.type->id == ZigTypeIdPointer); 20646 ZigType *promise_frame_type = coro_promise_ptr->value.type->data.pointer.child_type; 20647 assert(promise_frame_type->id == ZigTypeIdStruct); 20648 ZigType *promise_result_type = promise_frame_type->data.structure.fields[1].type_entry; 20649 20650 if (!type_can_fail(promise_result_type)) { 20651 return ir_const_void(ira, &instruction->base); 20652 } 20653 20654 IrInstruction *src_err_ret_trace_ptr = instruction->src_err_ret_trace_ptr->child; 20655 if (type_is_invalid(src_err_ret_trace_ptr->value.type)) 20656 return ira->codegen->invalid_instruction; 20657 20658 IrInstruction *dest_err_ret_trace_ptr = instruction->dest_err_ret_trace_ptr->child; 20659 if (type_is_invalid(dest_err_ret_trace_ptr->value.type)) 20660 return ira->codegen->invalid_instruction; 20661 20662 IrInstruction *result = ir_build_merge_err_ret_traces(&ira->new_irb, instruction->base.scope, 20663 instruction->base.source_node, coro_promise_ptr, src_err_ret_trace_ptr, dest_err_ret_trace_ptr); 20664 result->value.type = ira->codegen->builtin_types.entry_void; 20665 return result; 20666 } 20667 20668 static IrInstruction *ir_analyze_instruction_save_err_ret_addr(IrAnalyze *ira, IrInstructionSaveErrRetAddr *instruction) { 20669 IrInstruction *result = ir_build_save_err_ret_addr(&ira->new_irb, instruction->base.scope, 20670 instruction->base.source_node); 20671 result->value.type = ira->codegen->builtin_types.entry_void; 20672 return result; 20673 } 20674 20675 static IrInstruction *ir_analyze_instruction_mark_err_ret_trace_ptr(IrAnalyze *ira, IrInstructionMarkErrRetTracePtr *instruction) { 20676 IrInstruction *err_ret_trace_ptr = instruction->err_ret_trace_ptr->child; 20677 if (type_is_invalid(err_ret_trace_ptr->value.type)) 20678 return ira->codegen->invalid_instruction; 20679 20680 IrInstruction *result = ir_build_mark_err_ret_trace_ptr(&ira->new_irb, instruction->base.scope, 20681 instruction->base.source_node, err_ret_trace_ptr); 20682 result->value.type = ira->codegen->builtin_types.entry_void; 20683 return result; 20684 } 20685 20686 static IrInstruction *ir_analyze_instruction_sqrt(IrAnalyze *ira, IrInstructionSqrt *instruction) { 20687 ZigType *float_type = ir_resolve_type(ira, instruction->type->child); 20688 if (type_is_invalid(float_type)) 20689 return ira->codegen->invalid_instruction; 20690 20691 IrInstruction *op = instruction->op->child; 20692 if (type_is_invalid(op->value.type)) 20693 return ira->codegen->invalid_instruction; 20694 20695 bool ok_type = float_type->id == ZigTypeIdComptimeFloat || float_type->id == ZigTypeIdFloat; 20696 if (!ok_type) { 20697 ir_add_error(ira, instruction->type, buf_sprintf("@sqrt does not support type '%s'", buf_ptr(&float_type->name))); 20698 return ira->codegen->invalid_instruction; 20699 } 20700 20701 IrInstruction *casted_op = ir_implicit_cast(ira, op, float_type); 20702 if (type_is_invalid(casted_op->value.type)) 20703 return ira->codegen->invalid_instruction; 20704 20705 if (instr_is_comptime(casted_op)) { 20706 ConstExprValue *val = ir_resolve_const(ira, casted_op, UndefBad); 20707 if (!val) 20708 return ira->codegen->invalid_instruction; 20709 20710 IrInstruction *result = ir_const(ira, &instruction->base, float_type); 20711 ConstExprValue *out_val = &result->value; 20712 20713 if (float_type->id == ZigTypeIdComptimeFloat) { 20714 bigfloat_sqrt(&out_val->data.x_bigfloat, &val->data.x_bigfloat); 20715 } else if (float_type->id == ZigTypeIdFloat) { 20716 switch (float_type->data.floating.bit_count) { 20717 case 16: 20718 out_val->data.x_f16 = f16_sqrt(val->data.x_f16); 20719 break; 20720 case 32: 20721 out_val->data.x_f32 = sqrtf(val->data.x_f32); 20722 break; 20723 case 64: 20724 out_val->data.x_f64 = sqrt(val->data.x_f64); 20725 break; 20726 case 128: 20727 f128M_sqrt(&val->data.x_f128, &out_val->data.x_f128); 20728 break; 20729 default: 20730 zig_unreachable(); 20731 } 20732 } else { 20733 zig_unreachable(); 20734 } 20735 20736 return result; 20737 } 20738 20739 assert(float_type->id == ZigTypeIdFloat); 20740 if (float_type->data.floating.bit_count != 16 && 20741 float_type->data.floating.bit_count != 32 && 20742 float_type->data.floating.bit_count != 64) { 20743 ir_add_error(ira, instruction->type, buf_sprintf("compiler TODO: add implementation of sqrt for '%s'", buf_ptr(&float_type->name))); 20744 return ira->codegen->invalid_instruction; 20745 } 20746 20747 IrInstruction *result = ir_build_sqrt(&ira->new_irb, instruction->base.scope, 20748 instruction->base.source_node, nullptr, casted_op); 20749 result->value.type = float_type; 20750 return result; 20751 } 20752 20753 static IrInstruction *ir_analyze_instruction_enum_to_int(IrAnalyze *ira, IrInstructionEnumToInt *instruction) { 20754 Error err; 20755 IrInstruction *target = instruction->target->child; 20756 if (type_is_invalid(target->value.type)) 20757 return ira->codegen->invalid_instruction; 20758 20759 if (target->value.type->id != ZigTypeIdEnum) { 20760 ir_add_error(ira, instruction->target, 20761 buf_sprintf("expected enum, found type '%s'", buf_ptr(&target->value.type->name))); 20762 return ira->codegen->invalid_instruction; 20763 } 20764 20765 if ((err = type_resolve(ira->codegen, target->value.type, ResolveStatusZeroBitsKnown))) 20766 return ira->codegen->invalid_instruction; 20767 20768 ZigType *tag_type = target->value.type->data.enumeration.tag_int_type; 20769 20770 return ir_analyze_enum_to_int(ira, &instruction->base, target, tag_type); 20771 } 20772 20773 static IrInstruction *ir_analyze_instruction_int_to_enum(IrAnalyze *ira, IrInstructionIntToEnum *instruction) { 20774 Error err; 20775 IrInstruction *dest_type_value = instruction->dest_type->child; 20776 ZigType *dest_type = ir_resolve_type(ira, dest_type_value); 20777 if (type_is_invalid(dest_type)) 20778 return ira->codegen->invalid_instruction; 20779 20780 if (dest_type->id != ZigTypeIdEnum) { 20781 ir_add_error(ira, instruction->dest_type, 20782 buf_sprintf("expected enum, found type '%s'", buf_ptr(&dest_type->name))); 20783 return ira->codegen->invalid_instruction; 20784 } 20785 20786 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown))) 20787 return ira->codegen->invalid_instruction; 20788 20789 ZigType *tag_type = dest_type->data.enumeration.tag_int_type; 20790 20791 IrInstruction *target = instruction->target->child; 20792 if (type_is_invalid(target->value.type)) 20793 return ira->codegen->invalid_instruction; 20794 20795 IrInstruction *casted_target = ir_implicit_cast(ira, target, tag_type); 20796 if (type_is_invalid(casted_target->value.type)) 20797 return ira->codegen->invalid_instruction; 20798 20799 return ir_analyze_int_to_enum(ira, &instruction->base, casted_target, dest_type); 20800 } 20801 20802 static IrInstruction *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, IrInstructionCheckRuntimeScope *instruction) { 20803 IrInstruction *block_comptime_inst = instruction->scope_is_comptime->child; 20804 bool scope_is_comptime; 20805 if (!ir_resolve_bool(ira, block_comptime_inst, &scope_is_comptime)) 20806 return ira->codegen->invalid_instruction; 20807 20808 IrInstruction *is_comptime_inst = instruction->is_comptime->child; 20809 bool is_comptime; 20810 if (!ir_resolve_bool(ira, is_comptime_inst, &is_comptime)) 20811 return ira->codegen->invalid_instruction; 20812 20813 if (!scope_is_comptime && is_comptime) { 20814 ErrorMsg *msg = ir_add_error(ira, &instruction->base, 20815 buf_sprintf("comptime control flow inside runtime block")); 20816 add_error_note(ira->codegen, msg, block_comptime_inst->source_node, 20817 buf_sprintf("runtime block created here")); 20818 return ira->codegen->invalid_instruction; 20819 } 20820 20821 return ir_const_void(ira, &instruction->base); 20822 } 20823 20824 static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { 20825 switch (instruction->id) { 20826 case IrInstructionIdInvalid: 20827 case IrInstructionIdWidenOrShorten: 20828 case IrInstructionIdStructInit: 20829 case IrInstructionIdUnionInit: 20830 case IrInstructionIdStructFieldPtr: 20831 case IrInstructionIdUnionFieldPtr: 20832 case IrInstructionIdOptionalWrap: 20833 case IrInstructionIdErrWrapCode: 20834 case IrInstructionIdErrWrapPayload: 20835 case IrInstructionIdCast: 20836 zig_unreachable(); 20837 20838 case IrInstructionIdReturn: 20839 return ir_analyze_instruction_return(ira, (IrInstructionReturn *)instruction); 20840 case IrInstructionIdConst: 20841 return ir_analyze_instruction_const(ira, (IrInstructionConst *)instruction); 20842 case IrInstructionIdUnOp: 20843 return ir_analyze_instruction_un_op(ira, (IrInstructionUnOp *)instruction); 20844 case IrInstructionIdBinOp: 20845 return ir_analyze_instruction_bin_op(ira, (IrInstructionBinOp *)instruction); 20846 case IrInstructionIdDeclVar: 20847 return ir_analyze_instruction_decl_var(ira, (IrInstructionDeclVar *)instruction); 20848 case IrInstructionIdLoadPtr: 20849 return ir_analyze_instruction_load_ptr(ira, (IrInstructionLoadPtr *)instruction); 20850 case IrInstructionIdStorePtr: 20851 return ir_analyze_instruction_store_ptr(ira, (IrInstructionStorePtr *)instruction); 20852 case IrInstructionIdElemPtr: 20853 return ir_analyze_instruction_elem_ptr(ira, (IrInstructionElemPtr *)instruction); 20854 case IrInstructionIdVarPtr: 20855 return ir_analyze_instruction_var_ptr(ira, (IrInstructionVarPtr *)instruction); 20856 case IrInstructionIdFieldPtr: 20857 return ir_analyze_instruction_field_ptr(ira, (IrInstructionFieldPtr *)instruction); 20858 case IrInstructionIdCall: 20859 return ir_analyze_instruction_call(ira, (IrInstructionCall *)instruction); 20860 case IrInstructionIdBr: 20861 return ir_analyze_instruction_br(ira, (IrInstructionBr *)instruction); 20862 case IrInstructionIdCondBr: 20863 return ir_analyze_instruction_cond_br(ira, (IrInstructionCondBr *)instruction); 20864 case IrInstructionIdUnreachable: 20865 return ir_analyze_instruction_unreachable(ira, (IrInstructionUnreachable *)instruction); 20866 case IrInstructionIdPhi: 20867 return ir_analyze_instruction_phi(ira, (IrInstructionPhi *)instruction); 20868 case IrInstructionIdTypeOf: 20869 return ir_analyze_instruction_typeof(ira, (IrInstructionTypeOf *)instruction); 20870 case IrInstructionIdToPtrType: 20871 return ir_analyze_instruction_to_ptr_type(ira, (IrInstructionToPtrType *)instruction); 20872 case IrInstructionIdPtrTypeChild: 20873 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction); 20874 case IrInstructionIdSetCold: 20875 return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction); 20876 case IrInstructionIdSetRuntimeSafety: 20877 return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction); 20878 case IrInstructionIdSetFloatMode: 20879 return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction); 20880 case IrInstructionIdSliceType: 20881 return ir_analyze_instruction_slice_type(ira, (IrInstructionSliceType *)instruction); 20882 case IrInstructionIdAsm: 20883 return ir_analyze_instruction_asm(ira, (IrInstructionAsm *)instruction); 20884 case IrInstructionIdArrayType: 20885 return ir_analyze_instruction_array_type(ira, (IrInstructionArrayType *)instruction); 20886 case IrInstructionIdPromiseType: 20887 return ir_analyze_instruction_promise_type(ira, (IrInstructionPromiseType *)instruction); 20888 case IrInstructionIdSizeOf: 20889 return ir_analyze_instruction_size_of(ira, (IrInstructionSizeOf *)instruction); 20890 case IrInstructionIdTestNonNull: 20891 return ir_analyze_instruction_test_non_null(ira, (IrInstructionTestNonNull *)instruction); 20892 case IrInstructionIdUnwrapOptional: 20893 return ir_analyze_instruction_unwrap_maybe(ira, (IrInstructionUnwrapOptional *)instruction); 20894 case IrInstructionIdClz: 20895 return ir_analyze_instruction_clz(ira, (IrInstructionClz *)instruction); 20896 case IrInstructionIdCtz: 20897 return ir_analyze_instruction_ctz(ira, (IrInstructionCtz *)instruction); 20898 case IrInstructionIdPopCount: 20899 return ir_analyze_instruction_pop_count(ira, (IrInstructionPopCount *)instruction); 20900 case IrInstructionIdSwitchBr: 20901 return ir_analyze_instruction_switch_br(ira, (IrInstructionSwitchBr *)instruction); 20902 case IrInstructionIdSwitchTarget: 20903 return ir_analyze_instruction_switch_target(ira, (IrInstructionSwitchTarget *)instruction); 20904 case IrInstructionIdSwitchVar: 20905 return ir_analyze_instruction_switch_var(ira, (IrInstructionSwitchVar *)instruction); 20906 case IrInstructionIdUnionTag: 20907 return ir_analyze_instruction_union_tag(ira, (IrInstructionUnionTag *)instruction); 20908 case IrInstructionIdImport: 20909 return ir_analyze_instruction_import(ira, (IrInstructionImport *)instruction); 20910 case IrInstructionIdArrayLen: 20911 return ir_analyze_instruction_array_len(ira, (IrInstructionArrayLen *)instruction); 20912 case IrInstructionIdRef: 20913 return ir_analyze_instruction_ref(ira, (IrInstructionRef *)instruction); 20914 case IrInstructionIdContainerInitList: 20915 return ir_analyze_instruction_container_init_list(ira, (IrInstructionContainerInitList *)instruction); 20916 case IrInstructionIdContainerInitFields: 20917 return ir_analyze_instruction_container_init_fields(ira, (IrInstructionContainerInitFields *)instruction); 20918 case IrInstructionIdCompileErr: 20919 return ir_analyze_instruction_compile_err(ira, (IrInstructionCompileErr *)instruction); 20920 case IrInstructionIdCompileLog: 20921 return ir_analyze_instruction_compile_log(ira, (IrInstructionCompileLog *)instruction); 20922 case IrInstructionIdErrName: 20923 return ir_analyze_instruction_err_name(ira, (IrInstructionErrName *)instruction); 20924 case IrInstructionIdTypeName: 20925 return ir_analyze_instruction_type_name(ira, (IrInstructionTypeName *)instruction); 20926 case IrInstructionIdCImport: 20927 return ir_analyze_instruction_c_import(ira, (IrInstructionCImport *)instruction); 20928 case IrInstructionIdCInclude: 20929 return ir_analyze_instruction_c_include(ira, (IrInstructionCInclude *)instruction); 20930 case IrInstructionIdCDefine: 20931 return ir_analyze_instruction_c_define(ira, (IrInstructionCDefine *)instruction); 20932 case IrInstructionIdCUndef: 20933 return ir_analyze_instruction_c_undef(ira, (IrInstructionCUndef *)instruction); 20934 case IrInstructionIdEmbedFile: 20935 return ir_analyze_instruction_embed_file(ira, (IrInstructionEmbedFile *)instruction); 20936 case IrInstructionIdCmpxchg: 20937 return ir_analyze_instruction_cmpxchg(ira, (IrInstructionCmpxchg *)instruction); 20938 case IrInstructionIdFence: 20939 return ir_analyze_instruction_fence(ira, (IrInstructionFence *)instruction); 20940 case IrInstructionIdTruncate: 20941 return ir_analyze_instruction_truncate(ira, (IrInstructionTruncate *)instruction); 20942 case IrInstructionIdIntCast: 20943 return ir_analyze_instruction_int_cast(ira, (IrInstructionIntCast *)instruction); 20944 case IrInstructionIdFloatCast: 20945 return ir_analyze_instruction_float_cast(ira, (IrInstructionFloatCast *)instruction); 20946 case IrInstructionIdErrSetCast: 20947 return ir_analyze_instruction_err_set_cast(ira, (IrInstructionErrSetCast *)instruction); 20948 case IrInstructionIdFromBytes: 20949 return ir_analyze_instruction_from_bytes(ira, (IrInstructionFromBytes *)instruction); 20950 case IrInstructionIdToBytes: 20951 return ir_analyze_instruction_to_bytes(ira, (IrInstructionToBytes *)instruction); 20952 case IrInstructionIdIntToFloat: 20953 return ir_analyze_instruction_int_to_float(ira, (IrInstructionIntToFloat *)instruction); 20954 case IrInstructionIdFloatToInt: 20955 return ir_analyze_instruction_float_to_int(ira, (IrInstructionFloatToInt *)instruction); 20956 case IrInstructionIdBoolToInt: 20957 return ir_analyze_instruction_bool_to_int(ira, (IrInstructionBoolToInt *)instruction); 20958 case IrInstructionIdIntType: 20959 return ir_analyze_instruction_int_type(ira, (IrInstructionIntType *)instruction); 20960 case IrInstructionIdBoolNot: 20961 return ir_analyze_instruction_bool_not(ira, (IrInstructionBoolNot *)instruction); 20962 case IrInstructionIdMemset: 20963 return ir_analyze_instruction_memset(ira, (IrInstructionMemset *)instruction); 20964 case IrInstructionIdMemcpy: 20965 return ir_analyze_instruction_memcpy(ira, (IrInstructionMemcpy *)instruction); 20966 case IrInstructionIdSlice: 20967 return ir_analyze_instruction_slice(ira, (IrInstructionSlice *)instruction); 20968 case IrInstructionIdMemberCount: 20969 return ir_analyze_instruction_member_count(ira, (IrInstructionMemberCount *)instruction); 20970 case IrInstructionIdMemberType: 20971 return ir_analyze_instruction_member_type(ira, (IrInstructionMemberType *)instruction); 20972 case IrInstructionIdMemberName: 20973 return ir_analyze_instruction_member_name(ira, (IrInstructionMemberName *)instruction); 20974 case IrInstructionIdBreakpoint: 20975 return ir_analyze_instruction_breakpoint(ira, (IrInstructionBreakpoint *)instruction); 20976 case IrInstructionIdReturnAddress: 20977 return ir_analyze_instruction_return_address(ira, (IrInstructionReturnAddress *)instruction); 20978 case IrInstructionIdFrameAddress: 20979 return ir_analyze_instruction_frame_address(ira, (IrInstructionFrameAddress *)instruction); 20980 case IrInstructionIdHandle: 20981 return ir_analyze_instruction_handle(ira, (IrInstructionHandle *)instruction); 20982 case IrInstructionIdAlignOf: 20983 return ir_analyze_instruction_align_of(ira, (IrInstructionAlignOf *)instruction); 20984 case IrInstructionIdOverflowOp: 20985 return ir_analyze_instruction_overflow_op(ira, (IrInstructionOverflowOp *)instruction); 20986 case IrInstructionIdTestErr: 20987 return ir_analyze_instruction_test_err(ira, (IrInstructionTestErr *)instruction); 20988 case IrInstructionIdUnwrapErrCode: 20989 return ir_analyze_instruction_unwrap_err_code(ira, (IrInstructionUnwrapErrCode *)instruction); 20990 case IrInstructionIdUnwrapErrPayload: 20991 return ir_analyze_instruction_unwrap_err_payload(ira, (IrInstructionUnwrapErrPayload *)instruction); 20992 case IrInstructionIdFnProto: 20993 return ir_analyze_instruction_fn_proto(ira, (IrInstructionFnProto *)instruction); 20994 case IrInstructionIdTestComptime: 20995 return ir_analyze_instruction_test_comptime(ira, (IrInstructionTestComptime *)instruction); 20996 case IrInstructionIdCheckSwitchProngs: 20997 return ir_analyze_instruction_check_switch_prongs(ira, (IrInstructionCheckSwitchProngs *)instruction); 20998 case IrInstructionIdCheckStatementIsVoid: 20999 return ir_analyze_instruction_check_statement_is_void(ira, (IrInstructionCheckStatementIsVoid *)instruction); 21000 case IrInstructionIdDeclRef: 21001 return ir_analyze_instruction_decl_ref(ira, (IrInstructionDeclRef *)instruction); 21002 case IrInstructionIdPanic: 21003 return ir_analyze_instruction_panic(ira, (IrInstructionPanic *)instruction); 21004 case IrInstructionIdPtrCast: 21005 return ir_analyze_instruction_ptr_cast(ira, (IrInstructionPtrCast *)instruction); 21006 case IrInstructionIdBitCast: 21007 return ir_analyze_instruction_bit_cast(ira, (IrInstructionBitCast *)instruction); 21008 case IrInstructionIdIntToPtr: 21009 return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); 21010 case IrInstructionIdPtrToInt: 21011 return ir_analyze_instruction_ptr_to_int(ira, (IrInstructionPtrToInt *)instruction); 21012 case IrInstructionIdTagName: 21013 return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionTagName *)instruction); 21014 case IrInstructionIdFieldParentPtr: 21015 return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); 21016 case IrInstructionIdByteOffsetOf: 21017 return ir_analyze_instruction_byte_offset_of(ira, (IrInstructionByteOffsetOf *)instruction); 21018 case IrInstructionIdBitOffsetOf: 21019 return ir_analyze_instruction_bit_offset_of(ira, (IrInstructionBitOffsetOf *)instruction); 21020 case IrInstructionIdTypeInfo: 21021 return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); 21022 case IrInstructionIdTypeId: 21023 return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); 21024 case IrInstructionIdSetEvalBranchQuota: 21025 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstructionSetEvalBranchQuota *)instruction); 21026 case IrInstructionIdPtrType: 21027 return ir_analyze_instruction_ptr_type(ira, (IrInstructionPtrType *)instruction); 21028 case IrInstructionIdAlignCast: 21029 return ir_analyze_instruction_align_cast(ira, (IrInstructionAlignCast *)instruction); 21030 case IrInstructionIdOpaqueType: 21031 return ir_analyze_instruction_opaque_type(ira, (IrInstructionOpaqueType *)instruction); 21032 case IrInstructionIdSetAlignStack: 21033 return ir_analyze_instruction_set_align_stack(ira, (IrInstructionSetAlignStack *)instruction); 21034 case IrInstructionIdArgType: 21035 return ir_analyze_instruction_arg_type(ira, (IrInstructionArgType *)instruction); 21036 case IrInstructionIdTagType: 21037 return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction); 21038 case IrInstructionIdExport: 21039 return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction); 21040 case IrInstructionIdErrorReturnTrace: 21041 return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction); 21042 case IrInstructionIdErrorUnion: 21043 return ir_analyze_instruction_error_union(ira, (IrInstructionErrorUnion *)instruction); 21044 case IrInstructionIdCancel: 21045 return ir_analyze_instruction_cancel(ira, (IrInstructionCancel *)instruction); 21046 case IrInstructionIdCoroId: 21047 return ir_analyze_instruction_coro_id(ira, (IrInstructionCoroId *)instruction); 21048 case IrInstructionIdCoroAlloc: 21049 return ir_analyze_instruction_coro_alloc(ira, (IrInstructionCoroAlloc *)instruction); 21050 case IrInstructionIdCoroSize: 21051 return ir_analyze_instruction_coro_size(ira, (IrInstructionCoroSize *)instruction); 21052 case IrInstructionIdCoroBegin: 21053 return ir_analyze_instruction_coro_begin(ira, (IrInstructionCoroBegin *)instruction); 21054 case IrInstructionIdGetImplicitAllocator: 21055 return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction); 21056 case IrInstructionIdCoroAllocFail: 21057 return ir_analyze_instruction_coro_alloc_fail(ira, (IrInstructionCoroAllocFail *)instruction); 21058 case IrInstructionIdCoroSuspend: 21059 return ir_analyze_instruction_coro_suspend(ira, (IrInstructionCoroSuspend *)instruction); 21060 case IrInstructionIdCoroEnd: 21061 return ir_analyze_instruction_coro_end(ira, (IrInstructionCoroEnd *)instruction); 21062 case IrInstructionIdCoroFree: 21063 return ir_analyze_instruction_coro_free(ira, (IrInstructionCoroFree *)instruction); 21064 case IrInstructionIdCoroResume: 21065 return ir_analyze_instruction_coro_resume(ira, (IrInstructionCoroResume *)instruction); 21066 case IrInstructionIdCoroSave: 21067 return ir_analyze_instruction_coro_save(ira, (IrInstructionCoroSave *)instruction); 21068 case IrInstructionIdCoroPromise: 21069 return ir_analyze_instruction_coro_promise(ira, (IrInstructionCoroPromise *)instruction); 21070 case IrInstructionIdCoroAllocHelper: 21071 return ir_analyze_instruction_coro_alloc_helper(ira, (IrInstructionCoroAllocHelper *)instruction); 21072 case IrInstructionIdAtomicRmw: 21073 return ir_analyze_instruction_atomic_rmw(ira, (IrInstructionAtomicRmw *)instruction); 21074 case IrInstructionIdAtomicLoad: 21075 return ir_analyze_instruction_atomic_load(ira, (IrInstructionAtomicLoad *)instruction); 21076 case IrInstructionIdPromiseResultType: 21077 return ir_analyze_instruction_promise_result_type(ira, (IrInstructionPromiseResultType *)instruction); 21078 case IrInstructionIdAwaitBookkeeping: 21079 return ir_analyze_instruction_await_bookkeeping(ira, (IrInstructionAwaitBookkeeping *)instruction); 21080 case IrInstructionIdSaveErrRetAddr: 21081 return ir_analyze_instruction_save_err_ret_addr(ira, (IrInstructionSaveErrRetAddr *)instruction); 21082 case IrInstructionIdAddImplicitReturnType: 21083 return ir_analyze_instruction_add_implicit_return_type(ira, (IrInstructionAddImplicitReturnType *)instruction); 21084 case IrInstructionIdMergeErrRetTraces: 21085 return ir_analyze_instruction_merge_err_ret_traces(ira, (IrInstructionMergeErrRetTraces *)instruction); 21086 case IrInstructionIdMarkErrRetTracePtr: 21087 return ir_analyze_instruction_mark_err_ret_trace_ptr(ira, (IrInstructionMarkErrRetTracePtr *)instruction); 21088 case IrInstructionIdSqrt: 21089 return ir_analyze_instruction_sqrt(ira, (IrInstructionSqrt *)instruction); 21090 case IrInstructionIdIntToErr: 21091 return ir_analyze_instruction_int_to_err(ira, (IrInstructionIntToErr *)instruction); 21092 case IrInstructionIdErrToInt: 21093 return ir_analyze_instruction_err_to_int(ira, (IrInstructionErrToInt *)instruction); 21094 case IrInstructionIdIntToEnum: 21095 return ir_analyze_instruction_int_to_enum(ira, (IrInstructionIntToEnum *)instruction); 21096 case IrInstructionIdEnumToInt: 21097 return ir_analyze_instruction_enum_to_int(ira, (IrInstructionEnumToInt *)instruction); 21098 case IrInstructionIdCheckRuntimeScope: 21099 return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction); 21100 } 21101 zig_unreachable(); 21102 } 21103 21104 static IrInstruction *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *old_instruction) { 21105 IrInstruction *new_instruction = ir_analyze_instruction_nocast(ira, old_instruction); 21106 assert(new_instruction->value.type != nullptr); 21107 old_instruction->child = new_instruction; 21108 return new_instruction; 21109 } 21110 21111 // This function attempts to evaluate IR code while doing type checking and other analysis. 21112 // It emits a new IrExecutable which is partially evaluated IR code. 21113 ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_exec, 21114 ZigType *expected_type, AstNode *expected_type_source_node) 21115 { 21116 assert(!old_exec->invalid); 21117 assert(expected_type == nullptr || !type_is_invalid(expected_type)); 21118 21119 IrAnalyze *ira = allocate<IrAnalyze>(1); 21120 old_exec->analysis = ira; 21121 ira->codegen = codegen; 21122 21123 ZigFn *fn_entry = exec_fn_entry(old_exec); 21124 bool is_async = fn_entry != nullptr && fn_entry->type_entry->data.fn.fn_type_id.cc == CallingConventionAsync; 21125 ira->explicit_return_type = is_async ? get_promise_type(codegen, expected_type) : expected_type; 21126 21127 ira->old_irb.codegen = codegen; 21128 ira->old_irb.exec = old_exec; 21129 21130 ira->new_irb.codegen = codegen; 21131 ira->new_irb.exec = new_exec; 21132 21133 ConstExprValue *vals = create_const_vals(ira->old_irb.exec->mem_slot_count); 21134 ira->exec_context.mem_slot_list.resize(ira->old_irb.exec->mem_slot_count); 21135 for (size_t i = 0; i < ira->exec_context.mem_slot_list.length; i += 1) { 21136 ira->exec_context.mem_slot_list.items[i] = &vals[i]; 21137 } 21138 21139 IrBasicBlock *old_entry_bb = ira->old_irb.exec->basic_block_list.at(0); 21140 IrBasicBlock *new_entry_bb = ir_get_new_bb(ira, old_entry_bb, nullptr); 21141 ir_ref_bb(new_entry_bb); 21142 ira->new_irb.current_basic_block = new_entry_bb; 21143 ira->old_bb_index = 0; 21144 21145 ir_start_bb(ira, old_entry_bb, nullptr); 21146 21147 while (ira->old_bb_index < ira->old_irb.exec->basic_block_list.length) { 21148 IrInstruction *old_instruction = ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index); 21149 21150 if (old_instruction->ref_count == 0 && !ir_has_side_effects(old_instruction)) { 21151 ira->instruction_index += 1; 21152 continue; 21153 } 21154 21155 IrInstruction *new_instruction = ir_analyze_instruction(ira, old_instruction); 21156 if (type_is_invalid(new_instruction->value.type) && ir_should_inline(new_exec, old_instruction->scope)) { 21157 return ira->codegen->builtin_types.entry_invalid; 21158 } 21159 21160 // unreachable instructions do their own control flow. 21161 if (new_instruction->value.type->id == ZigTypeIdUnreachable) 21162 continue; 21163 21164 ira->instruction_index += 1; 21165 } 21166 21167 if (new_exec->invalid) { 21168 return ira->codegen->builtin_types.entry_invalid; 21169 } else if (ira->src_implicit_return_type_list.length == 0) { 21170 return codegen->builtin_types.entry_unreachable; 21171 } else { 21172 return ir_resolve_peer_types(ira, expected_type_source_node, expected_type, ira->src_implicit_return_type_list.items, 21173 ira->src_implicit_return_type_list.length); 21174 } 21175 } 21176 21177 bool ir_has_side_effects(IrInstruction *instruction) { 21178 switch (instruction->id) { 21179 case IrInstructionIdInvalid: 21180 zig_unreachable(); 21181 case IrInstructionIdBr: 21182 case IrInstructionIdCondBr: 21183 case IrInstructionIdSwitchBr: 21184 case IrInstructionIdDeclVar: 21185 case IrInstructionIdStorePtr: 21186 case IrInstructionIdCall: 21187 case IrInstructionIdReturn: 21188 case IrInstructionIdUnreachable: 21189 case IrInstructionIdSetCold: 21190 case IrInstructionIdSetRuntimeSafety: 21191 case IrInstructionIdSetFloatMode: 21192 case IrInstructionIdImport: 21193 case IrInstructionIdCompileErr: 21194 case IrInstructionIdCompileLog: 21195 case IrInstructionIdCImport: 21196 case IrInstructionIdCInclude: 21197 case IrInstructionIdCDefine: 21198 case IrInstructionIdCUndef: 21199 case IrInstructionIdCmpxchg: 21200 case IrInstructionIdFence: 21201 case IrInstructionIdMemset: 21202 case IrInstructionIdMemcpy: 21203 case IrInstructionIdBreakpoint: 21204 case IrInstructionIdOverflowOp: // TODO when we support multiple returns this can be side effect free 21205 case IrInstructionIdCheckSwitchProngs: 21206 case IrInstructionIdCheckStatementIsVoid: 21207 case IrInstructionIdCheckRuntimeScope: 21208 case IrInstructionIdPanic: 21209 case IrInstructionIdSetEvalBranchQuota: 21210 case IrInstructionIdPtrType: 21211 case IrInstructionIdSetAlignStack: 21212 case IrInstructionIdExport: 21213 case IrInstructionIdCancel: 21214 case IrInstructionIdCoroId: 21215 case IrInstructionIdCoroBegin: 21216 case IrInstructionIdCoroAllocFail: 21217 case IrInstructionIdCoroEnd: 21218 case IrInstructionIdCoroResume: 21219 case IrInstructionIdCoroSave: 21220 case IrInstructionIdCoroAllocHelper: 21221 case IrInstructionIdAwaitBookkeeping: 21222 case IrInstructionIdSaveErrRetAddr: 21223 case IrInstructionIdAddImplicitReturnType: 21224 case IrInstructionIdMergeErrRetTraces: 21225 case IrInstructionIdMarkErrRetTracePtr: 21226 case IrInstructionIdAtomicRmw: 21227 return true; 21228 21229 case IrInstructionIdPhi: 21230 case IrInstructionIdUnOp: 21231 case IrInstructionIdBinOp: 21232 case IrInstructionIdLoadPtr: 21233 case IrInstructionIdConst: 21234 case IrInstructionIdCast: 21235 case IrInstructionIdContainerInitList: 21236 case IrInstructionIdContainerInitFields: 21237 case IrInstructionIdStructInit: 21238 case IrInstructionIdUnionInit: 21239 case IrInstructionIdFieldPtr: 21240 case IrInstructionIdElemPtr: 21241 case IrInstructionIdVarPtr: 21242 case IrInstructionIdTypeOf: 21243 case IrInstructionIdToPtrType: 21244 case IrInstructionIdPtrTypeChild: 21245 case IrInstructionIdArrayLen: 21246 case IrInstructionIdStructFieldPtr: 21247 case IrInstructionIdUnionFieldPtr: 21248 case IrInstructionIdArrayType: 21249 case IrInstructionIdPromiseType: 21250 case IrInstructionIdSliceType: 21251 case IrInstructionIdSizeOf: 21252 case IrInstructionIdTestNonNull: 21253 case IrInstructionIdUnwrapOptional: 21254 case IrInstructionIdClz: 21255 case IrInstructionIdCtz: 21256 case IrInstructionIdPopCount: 21257 case IrInstructionIdSwitchVar: 21258 case IrInstructionIdSwitchTarget: 21259 case IrInstructionIdUnionTag: 21260 case IrInstructionIdRef: 21261 case IrInstructionIdEmbedFile: 21262 case IrInstructionIdTruncate: 21263 case IrInstructionIdIntType: 21264 case IrInstructionIdBoolNot: 21265 case IrInstructionIdSlice: 21266 case IrInstructionIdMemberCount: 21267 case IrInstructionIdMemberType: 21268 case IrInstructionIdMemberName: 21269 case IrInstructionIdAlignOf: 21270 case IrInstructionIdReturnAddress: 21271 case IrInstructionIdFrameAddress: 21272 case IrInstructionIdHandle: 21273 case IrInstructionIdTestErr: 21274 case IrInstructionIdUnwrapErrCode: 21275 case IrInstructionIdOptionalWrap: 21276 case IrInstructionIdErrWrapCode: 21277 case IrInstructionIdErrWrapPayload: 21278 case IrInstructionIdFnProto: 21279 case IrInstructionIdTestComptime: 21280 case IrInstructionIdPtrCast: 21281 case IrInstructionIdBitCast: 21282 case IrInstructionIdWidenOrShorten: 21283 case IrInstructionIdPtrToInt: 21284 case IrInstructionIdIntToPtr: 21285 case IrInstructionIdIntToEnum: 21286 case IrInstructionIdIntToErr: 21287 case IrInstructionIdErrToInt: 21288 case IrInstructionIdDeclRef: 21289 case IrInstructionIdErrName: 21290 case IrInstructionIdTypeName: 21291 case IrInstructionIdTagName: 21292 case IrInstructionIdFieldParentPtr: 21293 case IrInstructionIdByteOffsetOf: 21294 case IrInstructionIdBitOffsetOf: 21295 case IrInstructionIdTypeInfo: 21296 case IrInstructionIdTypeId: 21297 case IrInstructionIdAlignCast: 21298 case IrInstructionIdOpaqueType: 21299 case IrInstructionIdArgType: 21300 case IrInstructionIdTagType: 21301 case IrInstructionIdErrorReturnTrace: 21302 case IrInstructionIdErrorUnion: 21303 case IrInstructionIdGetImplicitAllocator: 21304 case IrInstructionIdCoroAlloc: 21305 case IrInstructionIdCoroSize: 21306 case IrInstructionIdCoroSuspend: 21307 case IrInstructionIdCoroFree: 21308 case IrInstructionIdCoroPromise: 21309 case IrInstructionIdPromiseResultType: 21310 case IrInstructionIdSqrt: 21311 case IrInstructionIdAtomicLoad: 21312 case IrInstructionIdIntCast: 21313 case IrInstructionIdFloatCast: 21314 case IrInstructionIdErrSetCast: 21315 case IrInstructionIdIntToFloat: 21316 case IrInstructionIdFloatToInt: 21317 case IrInstructionIdBoolToInt: 21318 case IrInstructionIdFromBytes: 21319 case IrInstructionIdToBytes: 21320 case IrInstructionIdEnumToInt: 21321 return false; 21322 21323 case IrInstructionIdAsm: 21324 { 21325 IrInstructionAsm *asm_instruction = (IrInstructionAsm *)instruction; 21326 return asm_instruction->has_side_effects; 21327 } 21328 case IrInstructionIdUnwrapErrPayload: 21329 { 21330 IrInstructionUnwrapErrPayload *unwrap_err_payload_instruction = 21331 (IrInstructionUnwrapErrPayload *)instruction; 21332 return unwrap_err_payload_instruction->safety_check_on; 21333 } 21334 } 21335 zig_unreachable(); 21336 }